Trait Ordination Plant Community Analysis

  1. traits

    1. above- and belowground

      1. height & SLA
    2. acquisitive vs. conservative resource-use strategies

      1. rooting depth
    3. collaborative vs. individual resource-use strategies

      1. fine root proportion

      2. thickness of roots

Goal: Examine how traits shift in community compositional (ordinational) space, placing each trait on an axis.

Author: Caryn D. Iwanaga

Updated: 01/24/2025

Libraries

library(tidyverse)
library(dplyr)
library(ggplot2)
library(httr) # read out Dropbox folders
library(vegan)
library(readxl)

Read in Data

cover.dat.labels <- read.csv("https://www.dropbox.com/scl/fi/up8nnzkcpchsr45f8cm92/Compost_Cover_LongClean.csv?rlkey=z2tvaj8t6khadef7ydz782zka&st=qwef9ys0&dl=1") %>%
  mutate(
    nut_trt = factor(ifelse(nut_trt =="C", "+compost", ifelse(nut_trt =="F", "+N fertilizer", ifelse(nut_trt =="N", "control", NA))), levels = c("control", "+N fertilizer", "+compost")),
    ppt_trt = ifelse(ppt_trt == "D", "dry", ifelse(ppt_trt == "XC", "control", ifelse(ppt_trt == "W", "wet", NA))))

Make site x species matrix

  1. Calculate relative abundances of species for each site
    1. confused how to aggregate abundances because even grouping by plotid (nut_trt and ppt_trt), year, species, and grazing history (block 1&2 – high, block 3&4 – low) and averaged, the sd are as high as 45.96!
      1. proceeded with these high sd to see what happens (ask Lauren)
    2. try how it is when you split everything by each block (more representative?)
site.df <- 
  cover.dat.labels[, c(1:7, 18:19)] %>% #subset columns
  mutate(
    grazing_hist = ifelse(block == 1 | block == 2, "high", ifelse(block == 3 | block == 4, "low", NA))
  ) %>% # separate by block (grazing intensities)
  group_by(nut_trt, ppt_trt, yr, code4, grazing_hist) %>% # make each code unique -- one value for species abundance for each trt
  summarise(
    # pct_cover,
    abundance = mean(pct_cover)
    # sd = sd(pct_cover)
  )
`summarise()` has grouped output by 'nut_trt', 'ppt_trt', 'yr', 'code4'. You can override using the `.groups` argument.
matrix0 <- spread(
  site.df, 
  code4, 
  abundance, 
  fill = 0)

# make rownames ----
rownames(matrix0) <- paste(matrix0$nut_trt, matrix0$ppt_trt, matrix0$yr, matrix0$grazing_hist, sep = "_")
Warning: Setting row names on a tibble is deprecated.
# delete columns ---- 
matrix <- matrix0[, c(5:79)]

# relativize data with Bray-Curtis dissimilarity
matrix.bray <- decostand(matrix, "total")
rownames(matrix.bray) <- rownames(matrix0)

Split matrix by each block as well

site.block.sd.df <- 
  cover.dat.labels[, c(1:7, 18:19)] %>% #subset columns
  group_by(nut_trt, ppt_trt, yr, code4, block) %>% # make each code unique -- one value for species abundance for each trt
  summarise(
    pct_cover,
    abundance = mean(pct_cover),
    sd = sd(pct_cover)
  )
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
Please use `reframe()` instead.
When switching from `summarise()` to `reframe()`, remember that `reframe()` always returns an ungrouped data frame and adjust accordingly.`summarise()` has grouped output by 'nut_trt', 'ppt_trt', 'yr', 'code4', 'block'. You can override using the `.groups` argument.

Run NMDS

Rules of thumb:

  • < 0.05 is excellent

  • 0.05-0.1 is good

  • 0.1-0.2 is fair

  • 0.2-0.3 is cause for concern…

  • > 0.3 is poor, random

All years – low & high grazing

Stress: fair

0.1966553 

Grouping by year and grazing history had most significant clustering shown.

metaMDS()
nmds.comp <- metaMDS(matrix.bray, k=2, trymax = 25)
Run 0 stress 0.2020736 
Run 1 stress 0.1970655 
... New best solution
... Procrustes: rmse 0.06573517  max resid 0.2315863 
Run 2 stress 0.2027495 
Run 3 stress 0.1992376 
Run 4 stress 0.2045952 
Run 5 stress 0.2026252 
Run 6 stress 0.2027495 
Run 7 stress 0.2093589 
Run 8 stress 0.2020736 
Run 9 stress 0.1970625 
... New best solution
... Procrustes: rmse 0.006290782  max resid 0.03755233 
Run 10 stress 0.2075871 
Run 11 stress 0.2133994 
Run 12 stress 0.213313 
Run 13 stress 0.2037336 
Run 14 stress 0.2027496 
Run 15 stress 0.2026295 
Run 16 stress 0.2043011 
Run 17 stress 0.20163 
Run 18 stress 0.2059418 
Run 19 stress 0.1973472 
... Procrustes: rmse 0.02205658  max resid 0.1152837 
Run 20 stress 0.2101999 
Run 21 stress 0.1970631 
... Procrustes: rmse 0.006111069  max resid 0.03747752 
Run 22 stress 0.2171655 
Run 23 stress 0.2017185 
Run 24 stress 0.1974235 
... Procrustes: rmse 0.02005767  max resid 0.1153592 
Run 25 stress 0.2033605 
*** Best solution was not repeated -- monoMDS stopping criteria:
    23: stress ratio > sratmax
     2: scale factor of the gradient < sfgrmin
nmds.comp # pretty not great stress

Call:
metaMDS(comm = matrix.bray, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray 
Distance: bray 

Dimensions: 2 
Stress:     0.1970625 
Stress type 1, weak ties
Best solution was not repeated after 25 tries
The best solution was from try 9 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray’ 
stressplot(nmds.comp)

plot(nmds.comp, type="t")


nmds1 <- as.data.frame(scores(nmds.comp, choices=c(1), display=c("sites"))) %>%
  mutate(matrix0[, c(0:4)])
nmds2 <- as.data.frame(scores(nmds.comp, choices=c(2), display=c("sites")))

nmds_dat <- cbind(nmds1, nmds2) %>%
Error: Incomplete expression:   select(nut_trt:grazing_hist, NMDS1, NMDS2)
plot
ggplot(nmds_dat, aes(NMDS1, NMDS2,  fill = nut_trt, color = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Nutrient Treatment") +
  custom_colors +
  scale_color_manual(
  values = c(
    "control" = rgb(220, 220, 220, maxColorValue = 255),      # Lighter Gray
    "+N fertilizer" = rgb(140, 40, 150, maxColorValue = 255), # Vibrant Purple
    "+compost" = rgb(220, 180, 60, maxColorValue = 255),       # Bright Golden Yellow
    "wet" = rgb(0, 0, 255, maxColorValue = 255),
    "dry" = rgb(183, 65, 14, maxColorValue = 255)
  )
)


ggplot(nmds_dat, aes(NMDS1, NMDS2, color = as.factor(yr), fill = as.factor(yr))) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Year")


ggplot(nmds_dat, aes(NMDS1, NMDS2, fill = as.factor(ppt_trt), color = as.factor(ppt_trt))) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Precipitation Treatment") +
  custom_colors +
  scale_color_manual(
  values = c(
    "control" = rgb(220, 220, 220, maxColorValue = 255),      # Lighter Gray
    "+N fertilizer" = rgb(140, 40, 150, maxColorValue = 255), # Vibrant Purple
    "+compost" = rgb(220, 180, 60, maxColorValue = 255),       # Bright Golden Yellow
    "wet" = rgb(0, 0, 255, maxColorValue = 255),
    "dry" = rgb(183, 65, 14, maxColorValue = 255)
  )
)


ggplot(nmds_dat, aes(NMDS1, NMDS2,  fill = as.factor(grazing_hist), color = as.factor(grazing_hist))) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Grazing History")


ggplot(nmds_dat, aes(NMDS1, NMDS2,  color = as.factor(grazing_hist), fill = as.factor(yr))) +
  geom_point(aes(fill = as.factor(yr)), shape = 21, size = 4, stroke = 1) +
  stat_ellipse(aes(color = as.factor(yr)), 
                geom = "polygon",
               fill = NA,
               size = 1) +
  labs(title = "Grouped by Grazing History & Year") +
  scale_color_manual(
  values = c(
    "low" = "cyan",
    "high" = "brown",
  "2019" = "salmon",
  "2020" = "limegreen",
  "2021" = "cornflowerblue")
  )

  
ggplot(nmds_dat, aes(NMDS1, NMDS2, color = nut_trt, fill = as.factor(yr))) +
  geom_point(shape = 21, size = 4, stroke = 1) +
  stat_ellipse(aes(color = as.factor(nut_trt)),
             geom = "polygon",
             fill = NA,  # Makes the ellipse transparent inside
             size = 1) +
  labs(title = "Grouped by Nutrient Treatment & Year") +
  scale_color_manual(
  values = c(
    "control" = rgb(220, 220, 220, maxColorValue = 255),      # Lighter Gray
    "+N fertilizer" = rgb(140, 40, 150, maxColorValue = 255), # Vibrant Purple
    "+compost" = rgb(220, 180, 60, maxColorValue = 255),       # Bright Golden Yellow
    "wet" = rgb(0, 0, 255, maxColorValue = 255),
    "dry" = rgb(183, 65, 14, maxColorValue = 255)
  )
)

All years – blocks

Stress: cause for concern

0.2329306
metaMDS()
nmds.block.comp <- metaMDS(matrix.block.bray, k=2, trymax = 25)
Run 0 stress 0.2329306 
Run 1 stress 0.243463 
Run 2 stress 0.2482815 
Run 3 stress 0.2498999 
Run 4 stress 0.2329786 
... Procrustes: rmse 0.002230422  max resid 0.01280587 
Run 5 stress 0.2333533 
... Procrustes: rmse 0.01157363  max resid 0.1126004 
Run 6 stress 0.2421491 
Run 7 stress 0.2443351 
Run 8 stress 0.2333565 
... Procrustes: rmse 0.01146138  max resid 0.1123691 
Run 9 stress 0.246737 
Run 10 stress 0.2561412 
Run 11 stress 0.2432135 
Run 12 stress 0.2557287 
Run 13 stress 0.2438602 
Run 14 stress 0.2496649 
Run 15 stress 0.2406222 
Run 16 stress 0.2594277 
Run 17 stress 0.2535404 
Run 18 stress 0.2329445 
... Procrustes: rmse 0.001578641  max resid 0.01195696 
Run 19 stress 0.2329307 
... Procrustes: rmse 4.0144e-05  max resid 0.000261745 
... Similar to previous best
Run 20 stress 0.236599 
*** Best solution repeated 1 times
nmds.block.comp

Call:
metaMDS(comm = matrix.block.bray, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.block.bray 
Distance: bray 

Dimensions: 2 
Stress:     0.2329306 
Stress type 1, weak ties
Best solution was repeated 1 time in 20 tries
The best solution was from try 0 (metric scaling or null solution)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.block.bray’ 
stressplot(nmds.block.comp)

plot(nmds.block.comp, type="t")


nmds1 <- as.data.frame(scores(nmds.block.comp, choices=c(1), display=c("sites"))) %>%
  mutate(matrix0.block[, c(0:4)])
nmds2 <- as.data.frame(scores(nmds.block.comp, choices=c(2), display=c("sites")))

nmds_dat.block <- cbind(nmds1, nmds2) %>%
  select(nut_trt:block, NMDS1, NMDS2)
plot
ggplot(nmds_dat.block, aes(NMDS1, NMDS2,  fill = nut_trt, color = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Nutrient Treatment - Blocks") +
  custom_colors +
  scale_color_manual(
  values = c(
    "control" = rgb(220, 220, 220, maxColorValue = 255),      # Lighter Gray
    "+N fertilizer" = rgb(140, 40, 150, maxColorValue = 255), # Vibrant Purple
    "+compost" = rgb(220, 180, 60, maxColorValue = 255),       # Bright Golden Yellow
    "wet" = rgb(0, 0, 255, maxColorValue = 255),
    "dry" = rgb(183, 65, 14, maxColorValue = 255)
  )
)


ggplot(nmds_dat.block, aes(NMDS1, NMDS2, color = as.factor(yr), fill = as.factor(yr))) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Year - Blocks")


ggplot(nmds_dat.block, aes(NMDS1, NMDS2, fill = as.factor(ppt_trt), color = as.factor(ppt_trt))) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Precipitation Treatment - Blocks") +
  custom_colors +
  scale_color_manual(
  values = c(
    "control" = rgb(220, 220, 220, maxColorValue = 255),      # Lighter Gray
    "+N fertilizer" = rgb(140, 40, 150, maxColorValue = 255), # Vibrant Purple
    "+compost" = rgb(220, 180, 60, maxColorValue = 255),       # Bright Golden Yellow
    "wet" = rgb(0, 0, 255, maxColorValue = 255),
    "dry" = rgb(183, 65, 14, maxColorValue = 255)
  )
)


ggplot(nmds_dat.block, aes(NMDS1, NMDS2,  fill = as.factor(block), color = as.factor(block))) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(type = "norm", size = 1, alpha = 0.5) + # Ellipses for each group
  labs(title = "Grouped by Block")


ggplot(nmds_dat.block, aes(NMDS1, NMDS2,  color = as.factor(block), fill = as.factor(yr))) +
  geom_point(aes(fill = as.factor(yr)), shape = 21, size = 4, stroke = 1) +
  stat_ellipse(aes(color = as.factor(block)), 
                geom = "polygon",
               fill = NA,
               size = 1) +
  labs(title = "Grouped by Block & Year - Blocks") +
  scale_color_manual(
  values = c(
    # "low" = "cyan",
    # "high" = "brown",
  "2019" = "salmon",
  "2020" = "limegreen",
  "2021" = "cornflowerblue")
  )

  
ggplot(nmds_dat.block, aes(NMDS1, NMDS2, color = nut_trt, fill = as.factor(yr))) +
  geom_point(shape = 21, size = 4, stroke = 1) +
  stat_ellipse(aes(color = as.factor(nut_trt)),
             geom = "polygon",
             fill = NA,  # Makes the ellipse transparent inside
             size = 1) +
  labs(title = "Grouped by Nutrient Treatment & Year - Blocks") +
  scale_color_manual(
  values = c(
    "control" = rgb(220, 220, 220, maxColorValue = 255),      # Lighter Gray
    "+N fertilizer" = rgb(140, 40, 150, maxColorValue = 255), # Vibrant Purple
    "+compost" = rgb(220, 180, 60, maxColorValue = 255),       # Bright Golden Yellow
    "wet" = rgb(0, 0, 255, maxColorValue = 255),
    "dry" = rgb(183, 65, 14, maxColorValue = 255)
  )
)

All years - LOW GRAZING ONLY

Stress: fair

0.1869068

data wrangling

# relativize data with Bray-Curtis dissimilarity
matrix.low <- matrix0 %>%
  filter(grazing_hist == "low")

row.low <- paste(matrix.low$nut_trt, matrix.low$ppt_trt, matrix.low$yr, matrix.low$grazing_hist, sep = "_")

matrix.low <- matrix.low[, c(5:79)]

rownames(matrix.low) <- row.low
Warning: Setting row names on a tibble is deprecated.
matrix.bray.low <- decostand(matrix.low, "total")

metaMDS()

nmds.comp.low <- metaMDS(matrix.bray.low, k=2, trymax = 25)
Run 0 stress 0.2000574 
Run 1 stress 0.1869068 
... New best solution
... Procrustes: rmse 0.1206791  max resid 0.4645309 
Run 2 stress 0.1941799 
Run 3 stress 0.1876869 
Run 4 stress 0.1930573 
Run 5 stress 0.1869068 
... Procrustes: rmse 8.072635e-05  max resid 0.0002281104 
... Similar to previous best
Run 6 stress 0.1908791 
Run 7 stress 0.1942011 
Run 8 stress 0.2045135 
Run 9 stress 0.2142868 
Run 10 stress 0.2264618 
Run 11 stress 0.1876848 
Run 12 stress 0.201295 
Run 13 stress 0.2013001 
Run 14 stress 0.2298215 
Run 15 stress 0.2303754 
Run 16 stress 0.1941799 
Run 17 stress 0.2066946 
Run 18 stress 0.2237619 
Run 19 stress 0.1941799 
Run 20 stress 0.2122824 
*** Best solution repeated 1 times
nmds.comp.low # pretty not great stress

Call:
metaMDS(comm = matrix.bray.low, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.low 
Distance: bray 

Dimensions: 2 
Stress:     0.1869068 
Stress type 1, weak ties
Best solution was repeated 1 time in 20 tries
The best solution was from try 1 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.low’ 
stressplot(nmds.comp.low)

plot(nmds.comp.low, type="t")


nmds1 <- as.data.frame(scores(nmds.comp.low, choices=c(1), display=c("sites"))) %>%
  mutate(
    nut_trt = sapply(strsplit(rownames(matrix.low), "_"), `[`, 1),
    ppt_trt = sapply(strsplit(rownames(matrix.low), "_"), `[`, 2),
    yr = sapply(strsplit(rownames(matrix.low), "_"), `[`, 3),
    grazing_hist = sapply(strsplit(rownames(matrix.low), "_"), `[`, 4)
  )
nmds2 <- as.data.frame(scores(nmds.comp.low, choices=c(2), display=c("sites")))

nmds_low_dat <- cbind(nmds1, nmds2) %>%
  select(nut_trt:grazing_hist, NMDS1, NMDS2)

plot

ggplot(nmds_low_dat, aes(NMDS1, NMDS2,  color = as.factor(yr), shape = nut_trt)) +
  geom_point(size = 3, stroke = 1) + 
  labs(title = "2019-2021 (LOW) - Grouping by Year & Nutrient Treatment")


ggplot(nmds_low_dat, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  labs(title = "2019-2021 (LOW) - Grouping by Nutrient Treatment")+ 
  custom_colors



ggplot(nmds_low_dat, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2019-2021 (LOW) - Grouping by Precipitation Treatment") 


# add year ellipses ---- 
ggplot(nmds_low_dat, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  stat_ellipse(aes(color = as.factor(yr)), 
                geom = "polygon",
               fill = NA,
               size = 1) +
  labs(title = "2019-2021 (LOW) - Grouping by Nutrient Treatment")+ 
  custom_colors

Make each individual year NMDS to see if there’s better stress

2019

data wrangling

# relativize data with Bray-Curtis dissimilarity
matrix.2019 <- matrix0 %>%
  filter(yr == 2019)

row.2019 <- paste(matrix.2019$nut_trt, matrix.2019$ppt_trt, matrix.2019$yr, matrix.2019$grazing_hist, sep = "_")

matrix.2019 <- matrix.2019[, c(5:79)]

rownames(matrix.2019) <- row.2019
Warning: Setting row names on a tibble is deprecated.
matrix.bray.2019 <- decostand(matrix.2019, "total")

nmds 2019

Stress: Excellent

0.0560178
metaMDS()
nmds.2019 <- metaMDS(matrix.bray.2019, k=2, trymax = 25)
Run 0 stress 0.0560178 
Run 1 stress 0.0560178 
... Procrustes: rmse 2.857261e-06  max resid 9.034415e-06 
... Similar to previous best
Run 2 stress 0.05905532 
Run 3 stress 0.07335646 
Run 4 stress 0.0560178 
... Procrustes: rmse 5.903723e-06  max resid 1.375655e-05 
... Similar to previous best
Run 5 stress 0.05960972 
Run 6 stress 0.07030125 
Run 7 stress 0.06384516 
Run 8 stress 0.05877078 
Run 9 stress 0.05960972 
Run 10 stress 0.06223098 
Run 11 stress 0.05877078 
Run 12 stress 0.05654879 
Run 13 stress 0.05905533 
Run 14 stress 0.06677855 
Run 15 stress 0.05877078 
Run 16 stress 0.05960972 
Run 17 stress 0.059968 
Run 18 stress 0.05957995 
Run 19 stress 0.05639216 
... Procrustes: rmse 0.008347172  max resid 0.02870258 
Run 20 stress 0.05639215 
... Procrustes: rmse 0.008300352  max resid 0.02861537 
*** Best solution repeated 2 times
nmds.2019 # pretty not great stress

Call:
metaMDS(comm = matrix.bray.2019, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.2019 
Distance: bray 

Dimensions: 2 
Stress:     0.0560178 
Stress type 1, weak ties
Best solution was repeated 2 times in 20 tries
The best solution was from try 0 (metric scaling or null solution)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.2019’ 
stressplot(nmds.2019)

plot(nmds.2019, type="t")


nmds1.2019 <- as.data.frame(scores(nmds.2019, choices=c(1), display=c("sites"))) %>%
  mutate(
    nut_trt = sapply(strsplit(rownames(matrix.2019), "_"), `[`, 1),
    ppt_trt = sapply(strsplit(rownames(matrix.2019), "_"), `[`, 2),
    yr = sapply(strsplit(rownames(matrix.2019), "_"), `[`, 3),
    grazing_hist = sapply(strsplit(rownames(matrix.2019), "_"), `[`, 4)
  )
nmds2.2019 <- as.data.frame(scores(nmds.2019, choices=c(2), display=c("sites")))

nmds_2019_dat <- cbind(nmds1.2019, nmds2.2019) %>%
  select(nut_trt:grazing_hist, NMDS1, NMDS2)
plot
ggplot(nmds_2019_dat, aes(NMDS1, NMDS2,  color = grazing_hist, shape = nut_trt)) +
  geom_point(size = 3, stroke = 1) + 
  labs(title = "2019 - Grouping by Grazing History & Nutrient Treatment")


ggplot(nmds_2019_dat, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  labs(title = "2019 - Grouping by Nutrient Treatment")+ 
  custom_colors



ggplot(nmds_2019_dat, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2019 - Grouping by Precipitation Treatment") 

2020

data wrangling

# relativize data with Bray-Curtis dissimilarity
matrix.2020 <- matrix0 %>%
  filter(yr == 2020)

row.2020 <- paste(matrix.2020$nut_trt, matrix.2020$ppt_trt, matrix.2020$yr, matrix.2020$grazing_hist, sep = "_")

matrix.2020 <- matrix.2020[, c(5:79)]

rownames(matrix.2020) <- row.2020
Warning: Setting row names on a tibble is deprecated.
matrix.bray.2020 <- decostand(matrix.2020, "total")

nmds 2020

Stress: fair

0.1522495
metaMDS()
nmds.2020 <- metaMDS(matrix.bray.2020, k=2, trymax = 25)
Run 0 stress 0.1524241 
Run 1 stress 0.1748537 
Run 2 stress 0.1584809 
Run 3 stress 0.1748534 
Run 4 stress 0.1692911 
Run 5 stress 0.153917 
Run 6 stress 0.1744239 
Run 7 stress 0.1524241 
... New best solution
... Procrustes: rmse 9.73555e-06  max resid 2.454011e-05 
... Similar to previous best
Run 8 stress 0.1625903 
Run 9 stress 0.1761789 
Run 10 stress 0.1830193 
Run 11 stress 0.1743562 
Run 12 stress 0.1584809 
Run 13 stress 0.1592892 
Run 14 stress 0.1866315 
Run 15 stress 0.1522045 
... New best solution
... Procrustes: rmse 0.02481256  max resid 0.06590007 
Run 16 stress 0.1524241 
... Procrustes: rmse 0.02481195  max resid 0.06599272 
Run 17 stress 0.1524241 
... Procrustes: rmse 0.02480968  max resid 0.06599522 
Run 18 stress 0.1633441 
Run 19 stress 0.1594877 
Run 20 stress 0.1522495 
... Procrustes: rmse 0.01182949  max resid 0.0373637 
Run 21 stress 0.1754284 
Run 22 stress 0.1595535 
Run 23 stress 0.1592892 
Run 24 stress 0.1872714 
Run 25 stress 0.3718387 
*** Best solution was not repeated -- monoMDS stopping criteria:
    20: stress ratio > sratmax
     5: scale factor of the gradient < sfgrmin
nmds.2020

Call:
metaMDS(comm = matrix.bray.2020, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.2020 
Distance: bray 

Dimensions: 2 
Stress:     0.1522045 
Stress type 1, weak ties
Best solution was not repeated after 25 tries
The best solution was from try 15 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.2020’ 
stressplot(nmds.2020)

plot(nmds.2020, type="t")


nmds1.2020 <- as.data.frame(scores(nmds.2020, choices=c(1), display=c("sites"))) %>%
  mutate(
    nut_trt = sapply(strsplit(rownames(matrix.2020), "_"), `[`, 1),
    ppt_trt = sapply(strsplit(rownames(matrix.2020), "_"), `[`, 2),
    yr = sapply(strsplit(rownames(matrix.2020), "_"), `[`, 3),
    grazing_hist = sapply(strsplit(rownames(matrix.2020), "_"), `[`, 4)
  )
nmds2.2020 <- as.data.frame(scores(nmds.2020, choices=c(2), display=c("sites")))

nmds_2020_dat <- cbind(nmds1.2020, nmds2.2020) %>%
  select(nut_trt:grazing_hist, NMDS1, NMDS2)
plot
ggplot(nmds_2020_dat, aes(NMDS1, NMDS2,  color = grazing_hist, shape = nut_trt)) +
  geom_point(size = 4, stroke = 1) + 
  labs(title = "2020 - Grouping by Grazing History & Nutrient Treatment") 


ggplot(nmds_2020_dat, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2020 - Grouping by Nutrient Treatment")


ggplot(nmds_2020_dat, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2020 - Grouping by Precipitation Treatment")

2021

data wrangling

# relativize data with Bray-Curtis dissimilarity
matrix.2021 <- matrix0 %>%
  filter(yr == 2021)

row.2021 <- paste(matrix.2021$nut_trt, matrix.2021$ppt_trt, matrix.2021$yr, matrix.2021$grazing_hist, sep = "_")

matrix.2021 <- matrix.2021[, c(5:79)]

rownames(matrix.2021) <- row.2021
Warning: Setting row names on a tibble is deprecated.
matrix.bray.2021 <- decostand(matrix.2021, "total")
2021 - LOW

Stress

0.08067789
# relativize data with Bray-Curtis dissimilarity
matrix.2021.1 <- matrix0 %>%
  filter(yr == 2021,
         grazing_hist == "low") 

row.2021.1 <- paste(matrix.2021.1$nut_trt, matrix.2021.1$ppt_trt, matrix.2021.1$yr, matrix.2021.1$grazing_hist, sep = "_")

matrix.2021.1 <- matrix.2021.1[, c(5:79)]

rownames(matrix.2021.1) <- row.2021.1
Warning: Setting row names on a tibble is deprecated.
matrix.bray.2021.1 <- decostand(matrix.2021.1, "total")
nmds.2021.1 <- metaMDS(matrix.bray.2021.1, k=2, trymax = 25)
Run 0 stress 0.08067789 
Run 1 stress 0.08067789 
... New best solution
... Procrustes: rmse 1.043483e-06  max resid 2.080421e-06 
... Similar to previous best
Run 2 stress 0.281194 
Run 3 stress 0.08067789 
... Procrustes: rmse 7.163003e-06  max resid 1.247917e-05 
... Similar to previous best
Run 4 stress 0.08067789 
... Procrustes: rmse 1.917534e-06  max resid 2.917769e-06 
... Similar to previous best
Run 5 stress 0.08067789 
... Procrustes: rmse 1.136837e-06  max resid 1.808009e-06 
... Similar to previous best
Run 6 stress 0.1316771 
Run 7 stress 0.1393682 
Run 8 stress 0.1393365 
Run 9 stress 0.1203381 
Run 10 stress 0.1407363 
Run 11 stress 0.1393679 
Run 12 stress 0.203941 
Run 13 stress 0.08067789 
... New best solution
... Procrustes: rmse 2.590951e-06  max resid 4.031e-06 
... Similar to previous best
Run 14 stress 0.3209238 
Run 15 stress 0.08067789 
... Procrustes: rmse 7.471908e-07  max resid 1.269384e-06 
... Similar to previous best
Run 16 stress 0.08067789 
... Procrustes: rmse 2.87688e-06  max resid 4.25236e-06 
... Similar to previous best
Run 17 stress 0.08067789 
... Procrustes: rmse 3.075425e-06  max resid 4.219029e-06 
... Similar to previous best
Run 18 stress 0.08067789 
... Procrustes: rmse 1.408884e-06  max resid 2.855274e-06 
... Similar to previous best
Run 19 stress 0.1203381 
Run 20 stress 0.1316771 
*** Best solution repeated 5 times
nmds.2021.1

Call:
metaMDS(comm = matrix.bray.2021.1, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.2021.1 
Distance: bray 

Dimensions: 2 
Stress:     0.08067789 
Stress type 1, weak ties
Best solution was repeated 5 times in 20 tries
The best solution was from try 13 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.2021.1’ 
stressplot(nmds.2021.1)

plot(nmds.2021.1, type="t")

dummy <- as.data.frame(scores(nmds.2021.1, choices=c(1), display=c("sites")))

nmds1.2021.1.df <- as.data.frame(scores(nmds.2021.1, choices=c(1), display=c("sites"))) %>%
  mutate(trt = rownames(dummy)) %>%
  separate(trt, c("nut_trt", "ppt_trt", "pr", "grazing_hist"), sep="_")

nmds2.2021.1 <- as.data.frame(scores(nmds.2021.1, choices=c(2), display=c("sites")))

nmds_2021_dat.1 <- cbind(nmds1.2021.1.df, nmds2.2021.1) %>%
  select(nut_trt:grazing_hist, NMDS1, NMDS2)
# ggplot(nmds_2021_dat.1, aes(NMDS1, NMDS2,  color = grazing_hist, shape = nut_trt)) +
#   geom_point(size = 4, stroke = 0.5) +
#   labs(title = "2021 - Grouping by Grazing History & Nutrient Treatment")

ggplot(nmds_2021_dat.1, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (LOW) - Grouping by Nutrient Treatment")


ggplot(nmds_2021_dat.1, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (LOW) - Grouping by Precipitation Treatment")

2021 - HIGH

Stress

0.08065034
# relativize data with Bray-Curtis dissimilarity
matrix.2021.2 <- matrix0 %>%
  filter(yr == 2021,
         grazing_hist == "high") 

row.2021.2 <- paste(matrix.2021.2$nut_trt, matrix.2021.2$ppt_trt, matrix.2021.2$yr, matrix.2021.2$grazing_hist, sep = "_")

matrix.2021.2 <- matrix.2021.2[, c(5:79)]

rownames(matrix.2021.2) <- row.2021.2
Warning: Setting row names on a tibble is deprecated.
matrix.bray.2021.2 <- decostand(matrix.2021.2, "total")
nmds.2021.2 <- metaMDS(matrix.bray.2021.2, k=2, trymax = 25)
Run 0 stress 0.08065034 
Run 1 stress 0.08065038 
... Procrustes: rmse 0.0001358001  max resid 0.0002698928 
... Similar to previous best
Run 2 stress 0.08065036 
... Procrustes: rmse 9.292653e-05  max resid 0.0001874718 
... Similar to previous best
Run 3 stress 0.08065038 
... Procrustes: rmse 0.0001229219  max resid 0.0002449743 
... Similar to previous best
Run 4 stress 0.08065035 
... Procrustes: rmse 3.520356e-05  max resid 6.170247e-05 
... Similar to previous best
Run 5 stress 0.08065034 
... New best solution
... Procrustes: rmse 8.595434e-06  max resid 1.124846e-05 
... Similar to previous best
Run 6 stress 0.08554815 
Run 7 stress 0.1378309 
Run 8 stress 0.08065034 
... Procrustes: rmse 5.366069e-05  max resid 9.474028e-05 
... Similar to previous best
Run 9 stress 0.08065038 
... Procrustes: rmse 0.0001135427  max resid 0.0002111442 
... Similar to previous best
Run 10 stress 0.08554818 
Run 11 stress 0.08065035 
... Procrustes: rmse 3.872519e-05  max resid 7.476398e-05 
... Similar to previous best
Run 12 stress 0.08554816 
Run 13 stress 0.2444752 
Run 14 stress 0.0806506 
... Procrustes: rmse 8.06033e-05  max resid 0.0001613536 
... Similar to previous best
Run 15 stress 0.08065034 
... Procrustes: rmse 2.33919e-05  max resid 4.241008e-05 
... Similar to previous best
Run 16 stress 0.08065034 
... Procrustes: rmse 3.80112e-05  max resid 8.818892e-05 
... Similar to previous best
Run 17 stress 0.08065037 
... Procrustes: rmse 0.000114044  max resid 0.0002171751 
... Similar to previous best
Run 18 stress 0.1460913 
Run 19 stress 0.1378308 
Run 20 stress 0.08065034 
... Procrustes: rmse 1.981241e-05  max resid 3.849244e-05 
... Similar to previous best
*** Best solution repeated 9 times
nmds.2021.2

Call:
metaMDS(comm = matrix.bray.2021.2, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.2021.2 
Distance: bray 

Dimensions: 2 
Stress:     0.08065034 
Stress type 1, weak ties
Best solution was repeated 9 times in 20 tries
The best solution was from try 5 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.2021.2’ 
stressplot(nmds.2021.2)

plot(nmds.2021.2, type="t")

dummy <- as.data.frame(scores(nmds.2021.2, choices=c(1), display=c("sites")))

nmds1.2021.2.df <- as.data.frame(scores(nmds.2021.2, choices=c(1), display=c("sites"))) %>%
  mutate(trt = rownames(dummy)) %>%
  separate(trt, c("nut_trt", "ppt_trt", "pr", "grazing_hist"), sep="_")

nmds2.2021.2 <- as.data.frame(scores(nmds.2021.2, choices=c(2), display=c("sites")))

nmds_2021_dat.2 <- cbind(nmds1.2021.2.df, nmds2.2021.2) %>%
  select(nut_trt:grazing_hist, NMDS1, NMDS2)
ggplot(nmds_2021_dat.2, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (HIGH) - Grouping by Nutrient Treatment")


ggplot(nmds_2021_dat.2, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (HIGH) - Grouping by Precipitation Treatment")

nmds 2021

Stress: fair

0.1230831
metaMDS()
nmds.2021 <- metaMDS(matrix.bray.2021, k=2, trymax = 25)
Run 0 stress 0.1232098 
Run 1 stress 0.1688205 
Run 2 stress 0.1232098 
... Procrustes: rmse 2.53337e-06  max resid 5.886927e-06 
... Similar to previous best
Run 3 stress 0.1421227 
Run 4 stress 0.1232098 
... Procrustes: rmse 4.710548e-06  max resid 9.729523e-06 
... Similar to previous best
Run 5 stress 0.1232098 
... Procrustes: rmse 1.075313e-05  max resid 2.292137e-05 
... Similar to previous best
Run 6 stress 0.1230831 
... New best solution
... Procrustes: rmse 0.044648  max resid 0.1321507 
Run 7 stress 0.132972 
Run 8 stress 0.1507048 
Run 9 stress 0.1232098 
... Procrustes: rmse 0.04464764  max resid 0.1315101 
Run 10 stress 0.1339879 
Run 11 stress 0.1230831 
... New best solution
... Procrustes: rmse 8.465681e-06  max resid 2.684727e-05 
... Similar to previous best
Run 12 stress 0.1232098 
... Procrustes: rmse 0.04464354  max resid 0.1315331 
Run 13 stress 0.1230831 
... New best solution
... Procrustes: rmse 8.230338e-06  max resid 2.599273e-05 
... Similar to previous best
Run 14 stress 0.1232098 
... Procrustes: rmse 0.04463946  max resid 0.1315179 
Run 15 stress 0.132972 
Run 16 stress 0.163317 
Run 17 stress 0.1230831 
... Procrustes: rmse 1.757901e-05  max resid 5.568918e-05 
... Similar to previous best
Run 18 stress 0.1339879 
Run 19 stress 0.1506988 
Run 20 stress 0.1522754 
*** Best solution repeated 2 times
nmds.2021

Call:
metaMDS(comm = matrix.bray.2021, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.2021 
Distance: bray 

Dimensions: 2 
Stress:     0.1230831 
Stress type 1, weak ties
Best solution was repeated 2 times in 20 tries
The best solution was from try 13 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.2021’ 
stressplot(nmds.2021)

plot(nmds.2021, type="t")


nmds1.2021 <- as.data.frame(scores(nmds.2021, choices=c(1), display=c("sites"))) %>%
  mutate(
    nut_trt = sapply(strsplit(rownames(matrix.2021), "_"), `[`, 1),
    ppt_trt = sapply(strsplit(rownames(matrix.2021), "_"), `[`, 2),
    yr = sapply(strsplit(rownames(matrix.2021), "_"), `[`, 3),
    grazing_hist = sapply(strsplit(rownames(matrix.2021), "_"), `[`, 4)
  )
nmds2.2021 <- as.data.frame(scores(nmds.2021, choices=c(2), display=c("sites")))

nmds_2021_dat <- cbind(nmds1.2021, nmds2.2021) %>%
  select(nut_trt:grazing_hist, NMDS1, NMDS2)
plot
ggplot(nmds_2021_dat, aes(NMDS1, NMDS2,  color = grazing_hist, shape = nut_trt)) +
  geom_point(size = 4, stroke = 0.5) +
  labs(title = "2021 - Grouping by Grazing History & Nutrient Treatment")


ggplot(nmds_2021_dat, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 - Grouping by Nutrient Treatment")


ggplot(nmds_2021_dat, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 - Grouping by Precipitation Treatment")

2021 — blocks

data wrangling

nmds 2021

Stress: fair

0.1702944
metaMDS()
plot
ggplot(nmds_2021_dat.block, aes(NMDS1, NMDS2,  color = block, shape = nut_trt)) +
  geom_point(size = 4, stroke = 0.5) +
  labs(title = "2021 (Block) - Grouping by Block & Nutrient Treatment")


ggplot(nmds_2021_dat.block, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (Block) - Grouping by Nutrient Treatment")


ggplot(nmds_2021_dat.block, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (Block) - Grouping by Precipitation Treatment")

2021 — blocks (LOW)

data wrangling

# relativize data with Bray-Curtis dissimilarity
matrix.2021.block.low <- matrix0.block %>%
  filter(yr == 2021,
         block == 3 | block == 4)

row.2021.block.low <- paste(matrix.2021.block.low$nut_trt, matrix.2021.block.low$ppt_trt, matrix.2021.block.low$yr, matrix.2021.block.low$block, sep = "_")

matrix.2021.block.low <- matrix.2021.block.low[, -c(0:4)]

rownames(matrix.2021.block.low) <- row.2021.block.low
Warning: Setting row names on a tibble is deprecated.
matrix.bray.block.2021.low <- decostand(matrix.2021.block.low, "total")

nmds 2021

Stress: fair

0.1282296
metaMDS()
nmds.2021.block.low <- metaMDS(matrix.bray.block.2021.low, k=2, trymax = 25)
Run 0 stress 0.1282296 
Run 1 stress 0.1627532 
Run 2 stress 0.1282296 
... New best solution
... Procrustes: rmse 2.97563e-05  max resid 6.730899e-05 
... Similar to previous best
Run 3 stress 0.1428149 
Run 4 stress 0.1282297 
... Procrustes: rmse 0.0002046582  max resid 0.0007350626 
... Similar to previous best
Run 5 stress 0.214776 
Run 6 stress 0.2000888 
Run 7 stress 0.1833574 
Run 8 stress 0.1282296 
... Procrustes: rmse 3.786655e-05  max resid 0.0001314048 
... Similar to previous best
Run 9 stress 0.2088749 
Run 10 stress 0.1785638 
Run 11 stress 0.1785638 
Run 12 stress 0.1282296 
... Procrustes: rmse 4.723376e-05  max resid 0.0001570042 
... Similar to previous best
Run 13 stress 0.2067318 
Run 14 stress 0.1428149 
Run 15 stress 0.1428149 
Run 16 stress 0.1282297 
... Procrustes: rmse 0.000151359  max resid 0.0005169016 
... Similar to previous best
Run 17 stress 0.1282296 
... New best solution
... Procrustes: rmse 2.1128e-05  max resid 6.391618e-05 
... Similar to previous best
Run 18 stress 0.1627539 
Run 19 stress 0.2006842 
Run 20 stress 0.2053314 
*** Best solution repeated 1 times
nmds.2021.block.low

Call:
metaMDS(comm = matrix.bray.block.2021.low, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.block.2021.low 
Distance: bray 

Dimensions: 2 
Stress:     0.1282296 
Stress type 1, weak ties
Best solution was repeated 1 time in 20 tries
The best solution was from try 17 (random start)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.block.2021.low’ 
stressplot(nmds.2021.block.low)

plot(nmds.2021.block.low, type="t")


nmds1.2021.block.low <- as.data.frame(scores(nmds.2021.block.low, choices=c(1), display=c("sites"))) %>%
  mutate(
    nut_trt = sapply(strsplit(rownames(matrix.2021.block.low), "_"), `[`, 1),
    ppt_trt = sapply(strsplit(rownames(matrix.2021.block.low), "_"), `[`, 2),
    yr = sapply(strsplit(rownames(matrix.2021.block.low), "_"), `[`, 3),
    block = sapply(strsplit(rownames(matrix.2021.block.low), "_"), `[`, 4)
  )
nmds2.2021.block.low <- as.data.frame(scores(nmds.2021.block.low, choices=c(2), display=c("sites")))

nmds_2021_dat.block.low <- cbind(nmds1.2021.block.low, nmds2.2021.block.low) %>%
  select(nut_trt:block, NMDS1, NMDS2)
plot
ggplot(nmds_2021_dat.block.low, aes(NMDS1, NMDS2,  color = block, shape = nut_trt)) +
  geom_point(size = 4, stroke = 0.5) +
  labs(title = "2021 (Block; LOW) - Grouping by Block & Nutrient Treatment")


ggplot(nmds_2021_dat.block.low, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (Block; LOW) - Grouping by Nutrient Treatment")


ggplot(nmds_2021_dat.block.low, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (Block; LOW) - Grouping by Precipitation Treatment")

2021 — blocks (HIGH)

data wrangling

nmds 2021

Stress: fair

0.1412997
metaMDS()
nmds.2021.block.high <- metaMDS(matrix.bray.block.2021.high, k=2, trymax = 25)
Run 0 stress 0.1412997 
Run 1 stress 0.1856239 
Run 2 stress 0.1856239 
Run 3 stress 0.1581575 
Run 4 stress 0.1581575 
Run 5 stress 0.1581575 
Run 6 stress 0.1430827 
Run 7 stress 0.1412997 
... Procrustes: rmse 0.0001557866  max resid 0.000502084 
... Similar to previous best
Run 8 stress 0.1412998 
... Procrustes: rmse 0.0002316353  max resid 0.0007498162 
... Similar to previous best
Run 9 stress 0.1581575 
Run 10 stress 0.1581575 
Run 11 stress 0.1430823 
Run 12 stress 0.1856239 
Run 13 stress 0.1581575 
Run 14 stress 0.1581576 
Run 15 stress 0.1581575 
Run 16 stress 0.1856239 
Run 17 stress 0.1581575 
Run 18 stress 0.1581574 
Run 19 stress 0.1430827 
Run 20 stress 0.1412998 
... Procrustes: rmse 0.0002058184  max resid 0.0006648583 
... Similar to previous best
*** Best solution repeated 3 times
nmds.2021.block.high

Call:
metaMDS(comm = matrix.bray.block.2021.high, k = 2, trymax = 25) 

global Multidimensional Scaling using monoMDS

Data:     matrix.bray.block.2021.high 
Distance: bray 

Dimensions: 2 
Stress:     0.1412997 
Stress type 1, weak ties
Best solution was repeated 3 times in 20 tries
The best solution was from try 0 (metric scaling or null solution)
Scaling: centring, PC rotation, halfchange scaling 
Species: expanded scores based on ‘matrix.bray.block.2021.high’ 
stressplot(nmds.2021.block.high)

plot(nmds.2021.block.high, type="t")


nmds1.2021.block.high <- as.data.frame(scores(nmds.2021.block.high, choices=c(1), display=c("sites"))) %>%
  mutate(
    nut_trt = sapply(strsplit(rownames(matrix.2021.block.high), "_"), `[`, 1),
    ppt_trt = sapply(strsplit(rownames(matrix.2021.block.high), "_"), `[`, 2),
    yr = sapply(strsplit(rownames(matrix.2021.block.high), "_"), `[`, 3),
    block = sapply(strsplit(rownames(matrix.2021.block.high), "_"), `[`, 4)
  )
nmds2.2021.block.high <- as.data.frame(scores(nmds.2021.block.high, choices=c(2), display=c("sites")))

nmds_2021_dat.block.high <- cbind(nmds1.2021.block.high, nmds2.2021.block.high) %>%
  select(nut_trt:block, NMDS1, NMDS2)
plot
ggplot(nmds_2021_dat.block.high, aes(NMDS1, NMDS2,  color = block, shape = nut_trt)) +
  geom_point(size = 4, stroke = 0.5) +
  labs(title = "2021 (Block; HIGH) - Grouping by Block & Nutrient Treatment")


ggplot(nmds_2021_dat.block.high, aes(NMDS1, NMDS2,  fill = nut_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (Block; HIGH) - Grouping by Nutrient Treatment")


ggplot(nmds_2021_dat.block.high, aes(NMDS1, NMDS2,  fill = ppt_trt)) +
  geom_point(shape = 21, size = 4, stroke = 0.5) + 
  custom_colors + 
  labs(title = "2021 (Block; HIGH) - Grouping by Precipitation Treatment")

Make species x trait matrix

Greenhouse traits

  • height, leaf dry matter content, specific leaf area, root mass fraction, relative growth rate, coarse root diameter, root density, specific root length of fine roots, specific root length of coarse roots

Field traits

  • height, leaf dry matter content, specific leaf area, seed mass, leaf C, leaf N

“H1: Pairing field results with a greenhouse 15 N experiment will allow us to relate species responses to their ability to uptake organic N”

“In addition, we will conduct a greenhouse experiment to isolate the mechanism (mineralized N vs organic N uptake rates ) by which compost may affect species composition”

Workflow plan:

  • overlay species trait data as vectors on the NMDS

    • only greenhouse traits available (only sla data from field)

      • use PC scores as composite trait axes OR

      • average the traits for each species

Read in trait data

Summarize trait data (GH) for each species

means

)

LS0tCnRpdGxlOiAiVHJhaXQgT3JkaW5hdGlvbiBQbGFudCBDb21tdW5pdHkgQW5hbHlzaXMiCmF1dGhvcjogIkNhcnluIEQuIEl3YW5hZ2EiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogeWVzCi0tLQoKIyBUcmFpdCBPcmRpbmF0aW9uIFBsYW50IENvbW11bml0eSBBbmFseXNpcwoKMS4gIHRyYWl0cwoKICAgIDEuICBhYm92ZS0gYW5kIGJlbG93Z3JvdW5kCgogICAgICAgIDEuICBoZWlnaHQgJiBTTEFcCgogICAgMi4gIGFjcXVpc2l0aXZlIHZzLiBjb25zZXJ2YXRpdmUgcmVzb3VyY2UtdXNlIHN0cmF0ZWdpZXMKCiAgICAgICAgMS4gIHJvb3RpbmcgZGVwdGgKCiAgICAzLiAgY29sbGFib3JhdGl2ZSB2cy4gaW5kaXZpZHVhbCByZXNvdXJjZS11c2Ugc3RyYXRlZ2llcwoKICAgICAgICAxLiAgZmluZSByb290IHByb3BvcnRpb24KCiAgICAgICAgMi4gIHRoaWNrbmVzcyBvZiByb290cwoKW0dvYWxdey51bmRlcmxpbmV9OiBFeGFtaW5lIGhvdyB0cmFpdHMgc2hpZnQgaW4gY29tbXVuaXR5IGNvbXBvc2l0aW9uYWwgKG9yZGluYXRpb25hbCkgc3BhY2UsIHBsYWNpbmcgZWFjaCB0cmFpdCBvbiBhbiBheGlzLgoKQXV0aG9yOiBDYXJ5biBELiBJd2FuYWdhCgpVcGRhdGVkOiAwMS8yNC8yMDI1CgojIyBMaWJyYXJpZXMKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGh0dHIpICMgcmVhZCBvdXQgRHJvcGJveCBmb2xkZXJzCmxpYnJhcnkodmVnYW4pCmxpYnJhcnkocmVhZHhsKQpgYGAKCiMjIFJlYWQgaW4gRGF0YQoKYGBge3J9CmNvdmVyLmRhdC5sYWJlbHMgPC0gcmVhZC5jc3YoImh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3NjbC9maS91cDhubnprY3BjaHNyNDVmOGNtOTIvQ29tcG9zdF9Db3Zlcl9Mb25nQ2xlYW4uY3N2P3Jsa2V5PXoydHZhajh0NmtoYWRlZjd5ZHo3ODJ6a2Emc3Q9cXdlZjl5czAmZGw9MSIpICU+JQogIG11dGF0ZSgKICAgIG51dF90cnQgPSBmYWN0b3IoaWZlbHNlKG51dF90cnQgPT0iQyIsICIrY29tcG9zdCIsIGlmZWxzZShudXRfdHJ0ID09IkYiLCAiK04gZmVydGlsaXplciIsIGlmZWxzZShudXRfdHJ0ID09Ik4iLCAiY29udHJvbCIsIE5BKSkpLCBsZXZlbHMgPSBjKCJjb250cm9sIiwgIitOIGZlcnRpbGl6ZXIiLCAiK2NvbXBvc3QiKSksCiAgICBwcHRfdHJ0ID0gaWZlbHNlKHBwdF90cnQgPT0gIkQiLCAiZHJ5IiwgaWZlbHNlKHBwdF90cnQgPT0gIlhDIiwgImNvbnRyb2wiLCBpZmVsc2UocHB0X3RydCA9PSAiVyIsICJ3ZXQiLCBOQSkpKSkKCgojIERlZmluZSBhIHJldXNhYmxlIGNvbG9yIHNjYWxlCiMgY3VzdG9tX2NvbG9ycyA8LSBzY2FsZV9maWxsX21hbnVhbCgKIyAgIHZhbHVlcyA9IGMoCiMgICAgICJjb250cm9sIiA9IHJnYigxOTUsIDE5NywgMTkzLCBtYXhDb2xvclZhbHVlID0gMjUwKSwKIyAgICAgIitOIGZlcnRpbGl6ZXIiID0gcmdiKDg3LCA2MiwgOTIsIG1heENvbG9yVmFsdWUgPSAyMjUpLAojICAgICAiK2NvbXBvc3QiID0gcmdiKDE2NywgMTU2LCAxMDksIG1heENvbG9yVmFsdWUgPSAyMjUpCiMgICApCiMgKQoKY3VzdG9tX2NvbG9ycyA8LSBzY2FsZV9maWxsX21hbnVhbCgKICB2YWx1ZXMgPSBjKAogICAgImNvbnRyb2wiID0gcmdiKDIyMCwgMjIwLCAyMjAsIG1heENvbG9yVmFsdWUgPSAyNTUpLCAgICAgICMgTGlnaHRlciBHcmF5CiAgICAiK04gZmVydGlsaXplciIgPSByZ2IoMTQwLCA0MCwgMTUwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgIyBWaWJyYW50IFB1cnBsZQogICAgIitjb21wb3N0IiA9IHJnYigyMjAsIDE4MCwgNjAsIG1heENvbG9yVmFsdWUgPSAyNTUpLCAgICAgICAjIEJyaWdodCBHb2xkZW4gWWVsbG93CiAgICAid2V0IiA9IHJnYigwLCAwLCAyNTUsIG1heENvbG9yVmFsdWUgPSAyNTUpLAogICAgImRyeSIgPSByZ2IoMTgzLCA2NSwgMTQsIG1heENvbG9yVmFsdWUgPSAyNTUpCiAgKQopCgojIFNldCBhIGdsb2JhbCB0aGVtZQp0aGVtZV9zZXQodGhlbWVfYncoKSkKYGBgCgojIyBNYWtlIHNpdGUgeCBzcGVjaWVzIG1hdHJpeAoKMS4gIENhbGN1bGF0ZSByZWxhdGl2ZSBhYnVuZGFuY2VzIG9mIHNwZWNpZXMgZm9yIGVhY2ggc2l0ZQogICAgMS4gIGNvbmZ1c2VkIGhvdyB0byBhZ2dyZWdhdGUgYWJ1bmRhbmNlcyBiZWNhdXNlIGV2ZW4gZ3JvdXBpbmcgYnkgcGxvdGlkIChudXRfdHJ0IGFuZCBwcHRfdHJ0KSwgeWVhciwgc3BlY2llcywgYW5kIGdyYXppbmcgaGlzdG9yeSAoYmxvY2sgMSYyIC0tIGhpZ2gsIGJsb2NrIDMmNCAtLSBsb3cpIGFuZCBhdmVyYWdlZCwgdGhlIHNkIGFyZSBhcyBoaWdoIGFzIDQ1Ljk2IQogICAgICAgIDEuICBwcm9jZWVkZWQgd2l0aCB0aGVzZSBoaWdoIHNkIHRvIHNlZSB3aGF0IGhhcHBlbnMgKGFzayBMYXVyZW4pCiAgICAyLiAgdHJ5IGhvdyBpdCBpcyB3aGVuIHlvdSBzcGxpdCBldmVyeXRoaW5nIGJ5IGVhY2ggYmxvY2sgKG1vcmUgcmVwcmVzZW50YXRpdmU/KQoKYGBge3J9CnNpdGUuZGYgPC0gCiAgY292ZXIuZGF0LmxhYmVsc1ssIGMoMTo3LCAxODoxOSldICU+JSAjc3Vic2V0IGNvbHVtbnMKICBtdXRhdGUoCiAgICBncmF6aW5nX2hpc3QgPSBpZmVsc2UoYmxvY2sgPT0gMSB8IGJsb2NrID09IDIsICJoaWdoIiwgaWZlbHNlKGJsb2NrID09IDMgfCBibG9jayA9PSA0LCAibG93IiwgTkEpKQogICkgJT4lICMgc2VwYXJhdGUgYnkgYmxvY2sgKGdyYXppbmcgaW50ZW5zaXRpZXMpCiAgZ3JvdXBfYnkobnV0X3RydCwgcHB0X3RydCwgeXIsIGNvZGU0LCBncmF6aW5nX2hpc3QpICU+JSAjIG1ha2UgZWFjaCBjb2RlIHVuaXF1ZSAtLSBvbmUgdmFsdWUgZm9yIHNwZWNpZXMgYWJ1bmRhbmNlIGZvciBlYWNoIHRydAogIHN1bW1hcmlzZSgKICAgICMgcGN0X2NvdmVyLAogICAgYWJ1bmRhbmNlID0gbWVhbihwY3RfY292ZXIpCiAgICAjIHNkID0gc2QocGN0X2NvdmVyKQogICkKCm1hdHJpeDAgPC0gc3ByZWFkKAogIHNpdGUuZGYsIAogIGNvZGU0LCAKICBhYnVuZGFuY2UsIAogIGZpbGwgPSAwKQoKIyBtYWtlIHJvd25hbWVzIC0tLS0Kcm93bmFtZXMobWF0cml4MCkgPC0gcGFzdGUobWF0cml4MCRudXRfdHJ0LCBtYXRyaXgwJHBwdF90cnQsIG1hdHJpeDAkeXIsIG1hdHJpeDAkZ3JhemluZ19oaXN0LCBzZXAgPSAiXyIpCgojIGRlbGV0ZSBjb2x1bW5zIC0tLS0gCm1hdHJpeCA8LSBtYXRyaXgwWywgYyg1Ojc5KV0KCiMgcmVsYXRpdml6ZSBkYXRhIHdpdGggQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eQptYXRyaXguYnJheSA8LSBkZWNvc3RhbmQobWF0cml4LCAidG90YWwiKQpyb3duYW1lcyhtYXRyaXguYnJheSkgPC0gcm93bmFtZXMobWF0cml4MCkKYGBgCgojIyMgU3BsaXQgbWF0cml4IGJ5IGVhY2ggYmxvY2sgYXMgd2VsbAoKYGBge3J9CnNpdGUuYmxvY2suZGYgPC0gCiAgY292ZXIuZGF0LmxhYmVsc1ssIGMoMTo3LCAxODoxOSldICU+JSAjc3Vic2V0IGNvbHVtbnMKICBncm91cF9ieShudXRfdHJ0LCBwcHRfdHJ0LCB5ciwgY29kZTQsIGJsb2NrKSAlPiUgIyBtYWtlIGVhY2ggY29kZSB1bmlxdWUgLS0gb25lIHZhbHVlIGZvciBzcGVjaWVzIGFidW5kYW5jZSBmb3IgZWFjaCB0cnQKICBzdW1tYXJpc2UoCiAgICAjIHBjdF9jb3ZlciwKICAgIGFidW5kYW5jZSA9IG1lYW4ocGN0X2NvdmVyKQogICAgIyBzZCA9IHNkKHBjdF9jb3ZlcikKICApCgpzaXRlLmJsb2NrLnNkLmRmIDwtIAogIGNvdmVyLmRhdC5sYWJlbHNbLCBjKDE6NywgMTg6MTkpXSAlPiUgI3N1YnNldCBjb2x1bW5zCiAgZ3JvdXBfYnkobnV0X3RydCwgcHB0X3RydCwgeXIsIGNvZGU0LCBibG9jaykgJT4lICMgbWFrZSBlYWNoIGNvZGUgdW5pcXVlIC0tIG9uZSB2YWx1ZSBmb3Igc3BlY2llcyBhYnVuZGFuY2UgZm9yIGVhY2ggdHJ0CiAgc3VtbWFyaXNlKAogICAgcGN0X2NvdmVyLAogICAgYWJ1bmRhbmNlID0gbWVhbihwY3RfY292ZXIpLAogICAgc2QgPSBzZChwY3RfY292ZXIpCiAgKQoKbWF0cml4MC5ibG9jayA8LSBzcHJlYWQoCiAgc2l0ZS5ibG9jay5kZiwgCiAgY29kZTQsIAogIGFidW5kYW5jZSwgCiAgZmlsbCA9IDApCgojIG1ha2Ugcm93bmFtZXMgLS0tLQpyb3duYW1lcyhtYXRyaXgwLmJsb2NrKSA8LSBwYXN0ZShtYXRyaXgwLmJsb2NrJG51dF90cnQsIG1hdHJpeDAuYmxvY2skcHB0X3RydCwgbWF0cml4MC5ibG9jayR5ciwgbWF0cml4MC5ibG9jayRibG9jaywgc2VwID0gIl8iKQoKIyBkZWxldGUgY29sdW1ucyAtLS0tIAptYXRyaXguYmxvY2sgPC0gbWF0cml4MC5ibG9ja1ssIC1jKDA6NCldCgojIHJlbGF0aXZpemUgZGF0YSB3aXRoIEJyYXktQ3VydGlzIGRpc3NpbWlsYXJpdHkKbWF0cml4LmJsb2NrLmJyYXkgPC0gZGVjb3N0YW5kKG1hdHJpeC5ibG9jaywgInRvdGFsIikKcm93bmFtZXMobWF0cml4LmJsb2NrLmJyYXkpIDwtIHJvd25hbWVzKG1hdHJpeDAuYmxvY2spCmBgYAoKIyMgUnVuIE5NRFMgCgpSdWxlcyBvZiB0aHVtYjoKCi0gICBcPCAwLjA1IGlzICoqZXhjZWxsZW50KioKCi0gICAwLjA1LTAuMSBpcyAqKmdvb2QqKgoKLSAgIDAuMS0wLjIgaXMgKipmYWlyKioKCi0gICAwLjItMC4zICoqaXMgY2F1c2UgZm9yIGNvbmNlcm4uLi4qKgoKLSAgIFw+IDAuMyAqKmlzIHBvb3IsIHJhbmRvbSoqCgojIyMgQWxsIHllYXJzIC0tIGxvdyAmIGhpZ2ggZ3JhemluZwoKW1N0cmVzczpdey51bmRlcmxpbmV9ICpmYWlyKgoKYGBgICAgICAgICAgCjAuMTk2NjU1MyAKYGBgCgpHcm91cGluZyBieSB5ZWFyIGFuZCBncmF6aW5nIGhpc3RvcnkgaGFkIG1vc3Qgc2lnbmlmaWNhbnQgY2x1c3RlcmluZyBzaG93bi4KCiMjIyMjIG1ldGFNRFMoKQoKYGBge3J9Cm5tZHMuY29tcCA8LSBtZXRhTURTKG1hdHJpeC5icmF5LCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLmNvbXAgIyBwcmV0dHkgbm90IGdyZWF0IHN0cmVzcwpzdHJlc3NwbG90KG5tZHMuY29tcCkKcGxvdChubWRzLmNvbXAsIHR5cGU9InQiKQoKbm1kczEgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy5jb21wLCBjaG9pY2VzPWMoMSksIGRpc3BsYXk9Yygic2l0ZXMiKSkpICU+JQogIG11dGF0ZShtYXRyaXgwWywgYygwOjQpXSkKbm1kczIgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy5jb21wLCBjaG9pY2VzPWMoMiksIGRpc3BsYXk9Yygic2l0ZXMiKSkpCgpubWRzX2RhdCA8LSBjYmluZChubWRzMSwgbm1kczIpICU+JQogIHNlbGVjdChudXRfdHJ0OmdyYXppbmdfaGlzdCwgTk1EUzEsIE5NRFMyKQoKYGBgCgojIyMjIyBwbG90CgpgYGB7cn0KZ2dwbG90KG5tZHNfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IG51dF90cnQsIGNvbG9yID0gbnV0X3RydCkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgc3RhdF9lbGxpcHNlKHR5cGUgPSAibm9ybSIsIHNpemUgPSAxLCBhbHBoYSA9IDAuNSkgKyAjIEVsbGlwc2VzIGZvciBlYWNoIGdyb3VwCiAgbGFicyh0aXRsZSA9ICJHcm91cGVkIGJ5IE51dHJpZW50IFRyZWF0bWVudCIpICsKICBjdXN0b21fY29sb3JzICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgdmFsdWVzID0gYygKICAgICJjb250cm9sIiA9IHJnYigyMjAsIDIyMCwgMjIwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgICAgICAjIExpZ2h0ZXIgR3JheQogICAgIitOIGZlcnRpbGl6ZXIiID0gcmdiKDE0MCwgNDAsIDE1MCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICMgVmlicmFudCBQdXJwbGUKICAgICIrY29tcG9zdCIgPSByZ2IoMjIwLCAxODAsIDYwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgICAgICAgIyBCcmlnaHQgR29sZGVuIFllbGxvdwogICAgIndldCIgPSByZ2IoMCwgMCwgMjU1LCBtYXhDb2xvclZhbHVlID0gMjU1KSwKICAgICJkcnkiID0gcmdiKDE4MywgNjUsIDE0LCBtYXhDb2xvclZhbHVlID0gMjU1KQogICkKKQoKZ2dwbG90KG5tZHNfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCBjb2xvciA9IGFzLmZhY3Rvcih5ciksIGZpbGwgPSBhcy5mYWN0b3IoeXIpKSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIiwgc2l6ZSA9IDEsIGFscGhhID0gMC41KSArICMgRWxsaXBzZXMgZm9yIGVhY2ggZ3JvdXAKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgYnkgWWVhciIpCgpnZ3Bsb3Qobm1kc19kYXQsIGFlcyhOTURTMSwgTk1EUzIsIGZpbGwgPSBhcy5mYWN0b3IocHB0X3RydCksIGNvbG9yID0gYXMuZmFjdG9yKHBwdF90cnQpKSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIiwgc2l6ZSA9IDEsIGFscGhhID0gMC41KSArICMgRWxsaXBzZXMgZm9yIGVhY2ggZ3JvdXAKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgYnkgUHJlY2lwaXRhdGlvbiBUcmVhdG1lbnQiKSArCiAgY3VzdG9tX2NvbG9ycyArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogIHZhbHVlcyA9IGMoCiAgICAiY29udHJvbCIgPSByZ2IoMjIwLCAyMjAsIDIyMCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICAgICAgIyBMaWdodGVyIEdyYXkKICAgICIrTiBmZXJ0aWxpemVyIiA9IHJnYigxNDAsIDQwLCAxNTAsIG1heENvbG9yVmFsdWUgPSAyNTUpLCAjIFZpYnJhbnQgUHVycGxlCiAgICAiK2NvbXBvc3QiID0gcmdiKDIyMCwgMTgwLCA2MCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICAgICAgICMgQnJpZ2h0IEdvbGRlbiBZZWxsb3cKICAgICJ3ZXQiID0gcmdiKDAsIDAsIDI1NSwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksCiAgICAiZHJ5IiA9IHJnYigxODMsIDY1LCAxNCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSkKICApCikKCmdncGxvdChubWRzX2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBhcy5mYWN0b3IoZ3JhemluZ19oaXN0KSwgY29sb3IgPSBhcy5mYWN0b3IoZ3JhemluZ19oaXN0KSkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgc3RhdF9lbGxpcHNlKHR5cGUgPSAibm9ybSIsIHNpemUgPSAxLCBhbHBoYSA9IDAuNSkgKyAjIEVsbGlwc2VzIGZvciBlYWNoIGdyb3VwCiAgbGFicyh0aXRsZSA9ICJHcm91cGVkIGJ5IEdyYXppbmcgSGlzdG9yeSIpCgpnZ3Bsb3Qobm1kc19kYXQsIGFlcyhOTURTMSwgTk1EUzIsICBjb2xvciA9IGFzLmZhY3RvcihncmF6aW5nX2hpc3QpLCBmaWxsID0gYXMuZmFjdG9yKHlyKSkpICsKICBnZW9tX3BvaW50KGFlcyhmaWxsID0gYXMuZmFjdG9yKHlyKSksIHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAxKSArCiAgc3RhdF9lbGxpcHNlKGFlcyhjb2xvciA9IGFzLmZhY3Rvcih5cikpLCAKICAgICAgICAgICAgICAgIGdlb20gPSAicG9seWdvbiIsCiAgICAgICAgICAgICAgIGZpbGwgPSBOQSwKICAgICAgICAgICAgICAgc2l6ZSA9IDEpICsKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgYnkgR3JhemluZyBIaXN0b3J5ICYgWWVhciIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgdmFsdWVzID0gYygKICAgICJsb3ciID0gImN5YW4iLAogICAgImhpZ2giID0gImJyb3duIiwKICAiMjAxOSIgPSAic2FsbW9uIiwKICAiMjAyMCIgPSAibGltZWdyZWVuIiwKICAiMjAyMSIgPSAiY29ybmZsb3dlcmJsdWUiKQogICkKICAKZ2dwbG90KG5tZHNfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCBjb2xvciA9IG51dF90cnQsIGZpbGwgPSBhcy5mYWN0b3IoeXIpKSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDEpICsKICBzdGF0X2VsbGlwc2UoYWVzKGNvbG9yID0gYXMuZmFjdG9yKG51dF90cnQpKSwKICAgICAgICAgICAgIGdlb20gPSAicG9seWdvbiIsCiAgICAgICAgICAgICBmaWxsID0gTkEsICAjIE1ha2VzIHRoZSBlbGxpcHNlIHRyYW5zcGFyZW50IGluc2lkZQogICAgICAgICAgICAgc2l6ZSA9IDEpICsKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgYnkgTnV0cmllbnQgVHJlYXRtZW50ICYgWWVhciIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgdmFsdWVzID0gYygKICAgICJjb250cm9sIiA9IHJnYigyMjAsIDIyMCwgMjIwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgICAgICAjIExpZ2h0ZXIgR3JheQogICAgIitOIGZlcnRpbGl6ZXIiID0gcmdiKDE0MCwgNDAsIDE1MCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICMgVmlicmFudCBQdXJwbGUKICAgICIrY29tcG9zdCIgPSByZ2IoMjIwLCAxODAsIDYwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgICAgICAgIyBCcmlnaHQgR29sZGVuIFllbGxvdwogICAgIndldCIgPSByZ2IoMCwgMCwgMjU1LCBtYXhDb2xvclZhbHVlID0gMjU1KSwKICAgICJkcnkiID0gcmdiKDE4MywgNjUsIDE0LCBtYXhDb2xvclZhbHVlID0gMjU1KQogICkKKQoKYGBgCgojIyMgQWxsIHllYXJzIC0tIGJsb2NrcwoKW1N0cmVzczpdey51bmRlcmxpbmV9ICpjYXVzZSBmb3IgY29uY2VybioKCmBgYCAgICAgICAgIAowLjIzMjkzMDYKYGBgCgojIyMjIyBtZXRhTURTKCkKCmBgYHtyfQpubWRzLmJsb2NrLmNvbXAgPC0gbWV0YU1EUyhtYXRyaXguYmxvY2suYnJheSwgaz0yLCB0cnltYXggPSAyNSkKbm1kcy5ibG9jay5jb21wCnN0cmVzc3Bsb3Qobm1kcy5ibG9jay5jb21wKQpwbG90KG5tZHMuYmxvY2suY29tcCwgdHlwZT0idCIpCgpubWRzMSA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLmJsb2NrLmNvbXAsIGNob2ljZXM9YygxKSwgZGlzcGxheT1jKCJzaXRlcyIpKSkgJT4lCiAgbXV0YXRlKG1hdHJpeDAuYmxvY2tbLCBjKDA6NCldKQpubWRzMiA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLmJsb2NrLmNvbXAsIGNob2ljZXM9YygyKSwgZGlzcGxheT1jKCJzaXRlcyIpKSkKCm5tZHNfZGF0LmJsb2NrIDwtIGNiaW5kKG5tZHMxLCBubWRzMikgJT4lCiAgc2VsZWN0KG51dF90cnQ6YmxvY2ssIE5NRFMxLCBOTURTMikKYGBgCgojIyMjIyBwbG90CgpgYGB7cn0KZ2dwbG90KG5tZHNfZGF0LmJsb2NrLCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IG51dF90cnQsIGNvbG9yID0gbnV0X3RydCkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgc3RhdF9lbGxpcHNlKHR5cGUgPSAibm9ybSIsIHNpemUgPSAxLCBhbHBoYSA9IDAuNSkgKyAjIEVsbGlwc2VzIGZvciBlYWNoIGdyb3VwCiAgbGFicyh0aXRsZSA9ICJHcm91cGVkIGJ5IE51dHJpZW50IFRyZWF0bWVudCAtIEJsb2NrcyIpICsKICBjdXN0b21fY29sb3JzICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgdmFsdWVzID0gYygKICAgICJjb250cm9sIiA9IHJnYigyMjAsIDIyMCwgMjIwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgICAgICAjIExpZ2h0ZXIgR3JheQogICAgIitOIGZlcnRpbGl6ZXIiID0gcmdiKDE0MCwgNDAsIDE1MCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICMgVmlicmFudCBQdXJwbGUKICAgICIrY29tcG9zdCIgPSByZ2IoMjIwLCAxODAsIDYwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgICAgICAgIyBCcmlnaHQgR29sZGVuIFllbGxvdwogICAgIndldCIgPSByZ2IoMCwgMCwgMjU1LCBtYXhDb2xvclZhbHVlID0gMjU1KSwKICAgICJkcnkiID0gcmdiKDE4MywgNjUsIDE0LCBtYXhDb2xvclZhbHVlID0gMjU1KQogICkKKQoKZ2dwbG90KG5tZHNfZGF0LmJsb2NrLCBhZXMoTk1EUzEsIE5NRFMyLCBjb2xvciA9IGFzLmZhY3Rvcih5ciksIGZpbGwgPSBhcy5mYWN0b3IoeXIpKSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIiwgc2l6ZSA9IDEsIGFscGhhID0gMC41KSArICMgRWxsaXBzZXMgZm9yIGVhY2ggZ3JvdXAKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgYnkgWWVhciAtIEJsb2NrcyIpCgpnZ3Bsb3Qobm1kc19kYXQuYmxvY2ssIGFlcyhOTURTMSwgTk1EUzIsIGZpbGwgPSBhcy5mYWN0b3IocHB0X3RydCksIGNvbG9yID0gYXMuZmFjdG9yKHBwdF90cnQpKSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBzdGF0X2VsbGlwc2UodHlwZSA9ICJub3JtIiwgc2l6ZSA9IDEsIGFscGhhID0gMC41KSArICMgRWxsaXBzZXMgZm9yIGVhY2ggZ3JvdXAKICBsYWJzKHRpdGxlID0gIkdyb3VwZWQgYnkgUHJlY2lwaXRhdGlvbiBUcmVhdG1lbnQgLSBCbG9ja3MiKSArCiAgY3VzdG9tX2NvbG9ycyArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogIHZhbHVlcyA9IGMoCiAgICAiY29udHJvbCIgPSByZ2IoMjIwLCAyMjAsIDIyMCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICAgICAgIyBMaWdodGVyIEdyYXkKICAgICIrTiBmZXJ0aWxpemVyIiA9IHJnYigxNDAsIDQwLCAxNTAsIG1heENvbG9yVmFsdWUgPSAyNTUpLCAjIFZpYnJhbnQgUHVycGxlCiAgICAiK2NvbXBvc3QiID0gcmdiKDIyMCwgMTgwLCA2MCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksICAgICAgICMgQnJpZ2h0IEdvbGRlbiBZZWxsb3cKICAgICJ3ZXQiID0gcmdiKDAsIDAsIDI1NSwgbWF4Q29sb3JWYWx1ZSA9IDI1NSksCiAgICAiZHJ5IiA9IHJnYigxODMsIDY1LCAxNCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSkKICApCikKCmdncGxvdChubWRzX2RhdC5ibG9jaywgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBhcy5mYWN0b3IoYmxvY2spLCBjb2xvciA9IGFzLmZhY3RvcihibG9jaykpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIHN0YXRfZWxsaXBzZSh0eXBlID0gIm5vcm0iLCBzaXplID0gMSwgYWxwaGEgPSAwLjUpICsgIyBFbGxpcHNlcyBmb3IgZWFjaCBncm91cAogIGxhYnModGl0bGUgPSAiR3JvdXBlZCBieSBCbG9jayIpCgpnZ3Bsb3Qobm1kc19kYXQuYmxvY2ssIGFlcyhOTURTMSwgTk1EUzIsICBjb2xvciA9IGFzLmZhY3RvcihibG9jayksIGZpbGwgPSBhcy5mYWN0b3IoeXIpKSkgKwogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBhcy5mYWN0b3IoeXIpKSwgc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDEpICsKICBzdGF0X2VsbGlwc2UoYWVzKGNvbG9yID0gYXMuZmFjdG9yKGJsb2NrKSksIAogICAgICAgICAgICAgICAgZ2VvbSA9ICJwb2x5Z29uIiwKICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICBzaXplID0gMSkgKwogIGxhYnModGl0bGUgPSAiR3JvdXBlZCBieSBCbG9jayAmIFllYXIgLSBCbG9ja3MiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogIHZhbHVlcyA9IGMoCiAgICAjICJsb3ciID0gImN5YW4iLAogICAgIyAiaGlnaCIgPSAiYnJvd24iLAogICIyMDE5IiA9ICJzYWxtb24iLAogICIyMDIwIiA9ICJsaW1lZ3JlZW4iLAogICIyMDIxIiA9ICJjb3JuZmxvd2VyYmx1ZSIpCiAgKQogIApnZ3Bsb3Qobm1kc19kYXQuYmxvY2ssIGFlcyhOTURTMSwgTk1EUzIsIGNvbG9yID0gbnV0X3RydCwgZmlsbCA9IGFzLmZhY3Rvcih5cikpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMSkgKwogIHN0YXRfZWxsaXBzZShhZXMoY29sb3IgPSBhcy5mYWN0b3IobnV0X3RydCkpLAogICAgICAgICAgICAgZ2VvbSA9ICJwb2x5Z29uIiwKICAgICAgICAgICAgIGZpbGwgPSBOQSwgICMgTWFrZXMgdGhlIGVsbGlwc2UgdHJhbnNwYXJlbnQgaW5zaWRlCiAgICAgICAgICAgICBzaXplID0gMSkgKwogIGxhYnModGl0bGUgPSAiR3JvdXBlZCBieSBOdXRyaWVudCBUcmVhdG1lbnQgJiBZZWFyIC0gQmxvY2tzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICB2YWx1ZXMgPSBjKAogICAgImNvbnRyb2wiID0gcmdiKDIyMCwgMjIwLCAyMjAsIG1heENvbG9yVmFsdWUgPSAyNTUpLCAgICAgICMgTGlnaHRlciBHcmF5CiAgICAiK04gZmVydGlsaXplciIgPSByZ2IoMTQwLCA0MCwgMTUwLCBtYXhDb2xvclZhbHVlID0gMjU1KSwgIyBWaWJyYW50IFB1cnBsZQogICAgIitjb21wb3N0IiA9IHJnYigyMjAsIDE4MCwgNjAsIG1heENvbG9yVmFsdWUgPSAyNTUpLCAgICAgICAjIEJyaWdodCBHb2xkZW4gWWVsbG93CiAgICAid2V0IiA9IHJnYigwLCAwLCAyNTUsIG1heENvbG9yVmFsdWUgPSAyNTUpLAogICAgImRyeSIgPSByZ2IoMTgzLCA2NSwgMTQsIG1heENvbG9yVmFsdWUgPSAyNTUpCiAgKQopCmBgYAoKIyMjIEFsbCB5ZWFycyAtIExPVyBHUkFaSU5HIE9OTFkKCltTdHJlc3M6XXsudW5kZXJsaW5lfSAqZmFpcioKCmBgYCAgICAgICAgIAowLjE4NjkwNjgKYGBgCgojIyMjIGRhdGEgd3JhbmdsaW5nCgpgYGB7cn0KIyByZWxhdGl2aXplIGRhdGEgd2l0aCBCcmF5LUN1cnRpcyBkaXNzaW1pbGFyaXR5Cm1hdHJpeC5sb3cgPC0gbWF0cml4MCAlPiUKICBmaWx0ZXIoZ3JhemluZ19oaXN0ID09ICJsb3ciKQoKcm93LmxvdyA8LSBwYXN0ZShtYXRyaXgubG93JG51dF90cnQsIG1hdHJpeC5sb3ckcHB0X3RydCwgbWF0cml4LmxvdyR5ciwgbWF0cml4LmxvdyRncmF6aW5nX2hpc3QsIHNlcCA9ICJfIikKCm1hdHJpeC5sb3cgPC0gbWF0cml4Lmxvd1ssIGMoNTo3OSldCgpyb3duYW1lcyhtYXRyaXgubG93KSA8LSByb3cubG93CgptYXRyaXguYnJheS5sb3cgPC0gZGVjb3N0YW5kKG1hdHJpeC5sb3csICJ0b3RhbCIpCmBgYAoKIyMjIyBtZXRhTURTKCkKCmBgYHtyfQpubWRzLmNvbXAubG93IDwtIG1ldGFNRFMobWF0cml4LmJyYXkubG93LCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLmNvbXAubG93ICMgcHJldHR5IG5vdCBncmVhdCBzdHJlc3MKc3RyZXNzcGxvdChubWRzLmNvbXAubG93KQpwbG90KG5tZHMuY29tcC5sb3csIHR5cGU9InQiKQoKbm1kczEgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy5jb21wLmxvdywgY2hvaWNlcz1jKDEpLCBkaXNwbGF5PWMoInNpdGVzIikpKSAlPiUKICBtdXRhdGUoCiAgICBudXRfdHJ0ID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC5sb3cpLCAiXyIpLCBgW2AsIDEpLAogICAgcHB0X3RydCA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXgubG93KSwgIl8iKSwgYFtgLCAyKSwKICAgIHlyID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC5sb3cpLCAiXyIpLCBgW2AsIDMpLAogICAgZ3JhemluZ19oaXN0ID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC5sb3cpLCAiXyIpLCBgW2AsIDQpCiAgKQpubWRzMiA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLmNvbXAubG93LCBjaG9pY2VzPWMoMiksIGRpc3BsYXk9Yygic2l0ZXMiKSkpCgpubWRzX2xvd19kYXQgPC0gY2JpbmQobm1kczEsIG5tZHMyKSAlPiUKICBzZWxlY3QobnV0X3RydDpncmF6aW5nX2hpc3QsIE5NRFMxLCBOTURTMikKYGBgCgojIyMjIHBsb3QKCmBgYHtyfQpnZ3Bsb3Qobm1kc19sb3dfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCAgY29sb3IgPSBhcy5mYWN0b3IoeXIpLCBzaGFwZSA9IG51dF90cnQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkgKyAKICBsYWJzKHRpdGxlID0gIjIwMTktMjAyMSAoTE9XKSAtIEdyb3VwaW5nIGJ5IFllYXIgJiBOdXRyaWVudCBUcmVhdG1lbnQiKQoKZ2dwbG90KG5tZHNfbG93X2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBsYWJzKHRpdGxlID0gIjIwMTktMjAyMSAoTE9XKSAtIEdyb3VwaW5nIGJ5IE51dHJpZW50IFRyZWF0bWVudCIpKyAKICBjdXN0b21fY29sb3JzCgoKZ2dwbG90KG5tZHNfbG93X2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBwcHRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDE5LTIwMjEgKExPVykgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpIAoKIyBhZGQgeWVhciBlbGxpcHNlcyAtLS0tIApnZ3Bsb3Qobm1kc19sb3dfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IG51dF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIHN0YXRfZWxsaXBzZShhZXMoY29sb3IgPSBhcy5mYWN0b3IoeXIpKSwgCiAgICAgICAgICAgICAgICBnZW9tID0gInBvbHlnb24iLAogICAgICAgICAgICAgICBmaWxsID0gTkEsCiAgICAgICAgICAgICAgIHNpemUgPSAxKSArCiAgbGFicyh0aXRsZSA9ICIyMDE5LTIwMjEgKExPVykgLSBHcm91cGluZyBieSBOdXRyaWVudCBUcmVhdG1lbnQiKSsgCiAgY3VzdG9tX2NvbG9ycwoKCmdncGxvdChubWRzX2xvd19kYXQsIGFlcyhOTURTMSwgTk1EUzIsICBmaWxsID0gcHB0X3RydCkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgICBzdGF0X2VsbGlwc2UoYWVzKGNvbG9yID0gYXMuZmFjdG9yKHlyKSksIAogICAgICAgICAgICAgICAgZ2VvbSA9ICJwb2x5Z29uIiwKICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICBzaXplID0gMSkgKwogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMTktMjAyMSAoTE9XKSAtIEdyb3VwaW5nIGJ5IFByZWNpcGl0YXRpb24gVHJlYXRtZW50IikgCmBgYAoKIyMgTWFrZSBlYWNoIGluZGl2aWR1YWwgeWVhciBOTURTIHRvIHNlZSBpZiB0aGVyZSdzIGJldHRlciBzdHJlc3MKCiMjIyAyMDE5CgojIyMjIGRhdGEgd3JhbmdsaW5nCgpgYGB7cn0KIyByZWxhdGl2aXplIGRhdGEgd2l0aCBCcmF5LUN1cnRpcyBkaXNzaW1pbGFyaXR5Cm1hdHJpeC4yMDE5IDwtIG1hdHJpeDAgJT4lCiAgZmlsdGVyKHlyID09IDIwMTkpCgpyb3cuMjAxOSA8LSBwYXN0ZShtYXRyaXguMjAxOSRudXRfdHJ0LCBtYXRyaXguMjAxOSRwcHRfdHJ0LCBtYXRyaXguMjAxOSR5ciwgbWF0cml4LjIwMTkkZ3JhemluZ19oaXN0LCBzZXAgPSAiXyIpCgptYXRyaXguMjAxOSA8LSBtYXRyaXguMjAxOVssIGMoNTo3OSldCgpyb3duYW1lcyhtYXRyaXguMjAxOSkgPC0gcm93LjIwMTkKCm1hdHJpeC5icmF5LjIwMTkgPC0gZGVjb3N0YW5kKG1hdHJpeC4yMDE5LCAidG90YWwiKQpgYGAKCiMjIyMgbm1kcyAyMDE5CgpbU3RyZXNzOl17LnVuZGVybGluZX0gKkV4Y2VsbGVudCoKCmBgYCAgICAgICAgIAowLjA1NjAxNzgKYGBgCgojIyMjIyBtZXRhTURTKCkKCmBgYHtyfQpubWRzLjIwMTkgPC0gbWV0YU1EUyhtYXRyaXguYnJheS4yMDE5LCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLjIwMTkgIyBwcmV0dHkgbm90IGdyZWF0IHN0cmVzcwpzdHJlc3NwbG90KG5tZHMuMjAxOSkKcGxvdChubWRzLjIwMTksIHR5cGU9InQiKQoKbm1kczEuMjAxOSA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMTksIGNob2ljZXM9YygxKSwgZGlzcGxheT1jKCJzaXRlcyIpKSkgJT4lCiAgbXV0YXRlKAogICAgbnV0X3RydCA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAxOSksICJfIiksIGBbYCwgMSksCiAgICBwcHRfdHJ0ID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC4yMDE5KSwgIl8iKSwgYFtgLCAyKSwKICAgIHlyID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC4yMDE5KSwgIl8iKSwgYFtgLCAzKSwKICAgIGdyYXppbmdfaGlzdCA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAxOSksICJfIiksIGBbYCwgNCkKICApCm5tZHMyLjIwMTkgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy4yMDE5LCBjaG9pY2VzPWMoMiksIGRpc3BsYXk9Yygic2l0ZXMiKSkpCgpubWRzXzIwMTlfZGF0IDwtIGNiaW5kKG5tZHMxLjIwMTksIG5tZHMyLjIwMTkpICU+JQogIHNlbGVjdChudXRfdHJ0OmdyYXppbmdfaGlzdCwgTk1EUzEsIE5NRFMyKQpgYGAKCiMjIyMjIHBsb3QKCmBgYHtyfQpnZ3Bsb3Qobm1kc18yMDE5X2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGNvbG9yID0gZ3JhemluZ19oaXN0LCBzaGFwZSA9IG51dF90cnQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkgKyAKICBsYWJzKHRpdGxlID0gIjIwMTkgLSBHcm91cGluZyBieSBHcmF6aW5nIEhpc3RvcnkgJiBOdXRyaWVudCBUcmVhdG1lbnQiKQoKZ2dwbG90KG5tZHNfMjAxOV9kYXQsIGFlcyhOTURTMSwgTk1EUzIsICBmaWxsID0gbnV0X3RydCkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgbGFicyh0aXRsZSA9ICIyMDE5IC0gR3JvdXBpbmcgYnkgTnV0cmllbnQgVHJlYXRtZW50IikrIAogIGN1c3RvbV9jb2xvcnMKCgpnZ3Bsb3Qobm1kc18yMDE5X2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBwcHRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDE5IC0gR3JvdXBpbmcgYnkgUHJlY2lwaXRhdGlvbiBUcmVhdG1lbnQiKSAKCmBgYAoKYGBgICAgICAgICAgCmBgYAoKIyMjIDIwMjAKCiMjIyMgZGF0YSB3cmFuZ2xpbmcKCmBgYHtyfQojIHJlbGF0aXZpemUgZGF0YSB3aXRoIEJyYXktQ3VydGlzIGRpc3NpbWlsYXJpdHkKbWF0cml4LjIwMjAgPC0gbWF0cml4MCAlPiUKICBmaWx0ZXIoeXIgPT0gMjAyMCkKCnJvdy4yMDIwIDwtIHBhc3RlKG1hdHJpeC4yMDIwJG51dF90cnQsIG1hdHJpeC4yMDIwJHBwdF90cnQsIG1hdHJpeC4yMDIwJHlyLCBtYXRyaXguMjAyMCRncmF6aW5nX2hpc3QsIHNlcCA9ICJfIikKCm1hdHJpeC4yMDIwIDwtIG1hdHJpeC4yMDIwWywgYyg1Ojc5KV0KCnJvd25hbWVzKG1hdHJpeC4yMDIwKSA8LSByb3cuMjAyMAoKbWF0cml4LmJyYXkuMjAyMCA8LSBkZWNvc3RhbmQobWF0cml4LjIwMjAsICJ0b3RhbCIpCmBgYAoKIyMjIyBubWRzIDIwMjAKCltTdHJlc3M6XXsudW5kZXJsaW5lfSAqZmFpcioKCmBgYCAgICAgICAgIAowLjE1MjI0OTUKYGBgCgojIyMjIyBtZXRhTURTKCkKCmBgYHtyfQpubWRzLjIwMjAgPC0gbWV0YU1EUyhtYXRyaXguYnJheS4yMDIwLCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLjIwMjAKc3RyZXNzcGxvdChubWRzLjIwMjApCnBsb3Qobm1kcy4yMDIwLCB0eXBlPSJ0IikKCm5tZHMxLjIwMjAgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy4yMDIwLCBjaG9pY2VzPWMoMSksIGRpc3BsYXk9Yygic2l0ZXMiKSkpICU+JQogIG11dGF0ZSgKICAgIG51dF90cnQgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjApLCAiXyIpLCBgW2AsIDEpLAogICAgcHB0X3RydCA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAyMCksICJfIiksIGBbYCwgMiksCiAgICB5ciA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAyMCksICJfIiksIGBbYCwgMyksCiAgICBncmF6aW5nX2hpc3QgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjApLCAiXyIpLCBgW2AsIDQpCiAgKQpubWRzMi4yMDIwIDwtIGFzLmRhdGEuZnJhbWUoc2NvcmVzKG5tZHMuMjAyMCwgY2hvaWNlcz1jKDIpLCBkaXNwbGF5PWMoInNpdGVzIikpKQoKbm1kc18yMDIwX2RhdCA8LSBjYmluZChubWRzMS4yMDIwLCBubWRzMi4yMDIwKSAlPiUKICBzZWxlY3QobnV0X3RydDpncmF6aW5nX2hpc3QsIE5NRFMxLCBOTURTMikKYGBgCgojIyMjIyBwbG90CgpgYGB7cn0KZ2dwbG90KG5tZHNfMjAyMF9kYXQsIGFlcyhOTURTMSwgTk1EUzIsICBjb2xvciA9IGdyYXppbmdfaGlzdCwgc2hhcGUgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIHN0cm9rZSA9IDEpICsgCiAgbGFicyh0aXRsZSA9ICIyMDIwIC0gR3JvdXBpbmcgYnkgR3JhemluZyBIaXN0b3J5ICYgTnV0cmllbnQgVHJlYXRtZW50IikgCgpnZ3Bsb3Qobm1kc18yMDIwX2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDIwIC0gR3JvdXBpbmcgYnkgTnV0cmllbnQgVHJlYXRtZW50IikKCmdncGxvdChubWRzXzIwMjBfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IHBwdF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMjAgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpCmBgYAoKIyMjIDIwMjEKCiMjIyMgZGF0YSB3cmFuZ2xpbmcKCmBgYHtyfQojIHJlbGF0aXZpemUgZGF0YSB3aXRoIEJyYXktQ3VydGlzIGRpc3NpbWlsYXJpdHkKbWF0cml4LjIwMjEgPC0gbWF0cml4MCAlPiUKICBmaWx0ZXIoeXIgPT0gMjAyMSkKCnJvdy4yMDIxIDwtIHBhc3RlKG1hdHJpeC4yMDIxJG51dF90cnQsIG1hdHJpeC4yMDIxJHBwdF90cnQsIG1hdHJpeC4yMDIxJHlyLCBtYXRyaXguMjAyMSRncmF6aW5nX2hpc3QsIHNlcCA9ICJfIikKCm1hdHJpeC4yMDIxIDwtIG1hdHJpeC4yMDIxWywgYyg1Ojc5KV0KCnJvd25hbWVzKG1hdHJpeC4yMDIxKSA8LSByb3cuMjAyMQoKbWF0cml4LmJyYXkuMjAyMSA8LSBkZWNvc3RhbmQobWF0cml4LjIwMjEsICJ0b3RhbCIpCmBgYAoKIyMjIyMgMjAyMSAtIExPVwoKU3RyZXNzCgpgYGAgICAgICAgICAKMC4wODA2Nzc4OQpgYGAKCmBgYHtyfQojIHJlbGF0aXZpemUgZGF0YSB3aXRoIEJyYXktQ3VydGlzIGRpc3NpbWlsYXJpdHkKbWF0cml4LjIwMjEuMSA8LSBtYXRyaXgwICU+JQogIGZpbHRlcih5ciA9PSAyMDIxLAogICAgICAgICBncmF6aW5nX2hpc3QgPT0gImxvdyIpIAoKcm93LjIwMjEuMSA8LSBwYXN0ZShtYXRyaXguMjAyMS4xJG51dF90cnQsIG1hdHJpeC4yMDIxLjEkcHB0X3RydCwgbWF0cml4LjIwMjEuMSR5ciwgbWF0cml4LjIwMjEuMSRncmF6aW5nX2hpc3QsIHNlcCA9ICJfIikKCm1hdHJpeC4yMDIxLjEgPC0gbWF0cml4LjIwMjEuMVssIGMoNTo3OSldCgpyb3duYW1lcyhtYXRyaXguMjAyMS4xKSA8LSByb3cuMjAyMS4xCgptYXRyaXguYnJheS4yMDIxLjEgPC0gZGVjb3N0YW5kKG1hdHJpeC4yMDIxLjEsICJ0b3RhbCIpCmBgYAoKYGBge3J9Cm5tZHMuMjAyMS4xIDwtIG1ldGFNRFMobWF0cml4LmJyYXkuMjAyMS4xLCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLjIwMjEuMQpzdHJlc3NwbG90KG5tZHMuMjAyMS4xKQpwbG90KG5tZHMuMjAyMS4xLCB0eXBlPSJ0IikKZHVtbXkgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy4yMDIxLjEsIGNob2ljZXM9YygxKSwgZGlzcGxheT1jKCJzaXRlcyIpKSkKCm5tZHMxLjIwMjEuMS5kZiA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuMSwgY2hvaWNlcz1jKDEpLCBkaXNwbGF5PWMoInNpdGVzIikpKSAlPiUKICBtdXRhdGUodHJ0ID0gcm93bmFtZXMoZHVtbXkpKSAlPiUKICBzZXBhcmF0ZSh0cnQsIGMoIm51dF90cnQiLCAicHB0X3RydCIsICJwciIsICJncmF6aW5nX2hpc3QiKSwgc2VwPSJfIikKCm5tZHMyLjIwMjEuMSA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuMSwgY2hvaWNlcz1jKDIpLCBkaXNwbGF5PWMoInNpdGVzIikpKQoKbm1kc18yMDIxX2RhdC4xIDwtIGNiaW5kKG5tZHMxLjIwMjEuMS5kZiwgbm1kczIuMjAyMS4xKSAlPiUKICBzZWxlY3QobnV0X3RydDpncmF6aW5nX2hpc3QsIE5NRFMxLCBOTURTMikKYGBgCgpgYGB7cn0KIyBnZ3Bsb3Qobm1kc18yMDIxX2RhdC4xLCBhZXMoTk1EUzEsIE5NRFMyLCAgY29sb3IgPSBncmF6aW5nX2hpc3QsIHNoYXBlID0gbnV0X3RydCkpICsKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKwojICAgbGFicyh0aXRsZSA9ICIyMDIxIC0gR3JvdXBpbmcgYnkgR3JhemluZyBIaXN0b3J5ICYgTnV0cmllbnQgVHJlYXRtZW50IikKCmdncGxvdChubWRzXzIwMjFfZGF0LjEsIGFlcyhOTURTMSwgTk1EUzIsICBmaWxsID0gbnV0X3RydCkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgY3VzdG9tX2NvbG9ycyArIAogIGxhYnModGl0bGUgPSAiMjAyMSAoTE9XKSAtIEdyb3VwaW5nIGJ5IE51dHJpZW50IFRyZWF0bWVudCIpCgpnZ3Bsb3Qobm1kc18yMDIxX2RhdC4xLCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IHBwdF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMjEgKExPVykgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpCmBgYAoKIyMjIyMgMjAyMSAtIEhJR0gKClN0cmVzcwoKYGBgICAgICAgICAgCjAuMDgwNjUwMzQKYGBgCgpgYGB7cn0KIyByZWxhdGl2aXplIGRhdGEgd2l0aCBCcmF5LUN1cnRpcyBkaXNzaW1pbGFyaXR5Cm1hdHJpeC4yMDIxLjIgPC0gbWF0cml4MCAlPiUKICBmaWx0ZXIoeXIgPT0gMjAyMSwKICAgICAgICAgZ3JhemluZ19oaXN0ID09ICJoaWdoIikgCgpyb3cuMjAyMS4yIDwtIHBhc3RlKG1hdHJpeC4yMDIxLjIkbnV0X3RydCwgbWF0cml4LjIwMjEuMiRwcHRfdHJ0LCBtYXRyaXguMjAyMS4yJHlyLCBtYXRyaXguMjAyMS4yJGdyYXppbmdfaGlzdCwgc2VwID0gIl8iKQoKbWF0cml4LjIwMjEuMiA8LSBtYXRyaXguMjAyMS4yWywgYyg1Ojc5KV0KCnJvd25hbWVzKG1hdHJpeC4yMDIxLjIpIDwtIHJvdy4yMDIxLjIKCm1hdHJpeC5icmF5LjIwMjEuMiA8LSBkZWNvc3RhbmQobWF0cml4LjIwMjEuMiwgInRvdGFsIikKYGBgCgpgYGB7cn0Kbm1kcy4yMDIxLjIgPC0gbWV0YU1EUyhtYXRyaXguYnJheS4yMDIxLjIsIGs9MiwgdHJ5bWF4ID0gMjUpCm5tZHMuMjAyMS4yCnN0cmVzc3Bsb3Qobm1kcy4yMDIxLjIpCnBsb3Qobm1kcy4yMDIxLjIsIHR5cGU9InQiKQpkdW1teSA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuMiwgY2hvaWNlcz1jKDEpLCBkaXNwbGF5PWMoInNpdGVzIikpKQoKbm1kczEuMjAyMS4yLmRmIDwtIGFzLmRhdGEuZnJhbWUoc2NvcmVzKG5tZHMuMjAyMS4yLCBjaG9pY2VzPWMoMSksIGRpc3BsYXk9Yygic2l0ZXMiKSkpICU+JQogIG11dGF0ZSh0cnQgPSByb3duYW1lcyhkdW1teSkpICU+JQogIHNlcGFyYXRlKHRydCwgYygibnV0X3RydCIsICJwcHRfdHJ0IiwgInByIiwgImdyYXppbmdfaGlzdCIpLCBzZXA9Il8iKQoKbm1kczIuMjAyMS4yIDwtIGFzLmRhdGEuZnJhbWUoc2NvcmVzKG5tZHMuMjAyMS4yLCBjaG9pY2VzPWMoMiksIGRpc3BsYXk9Yygic2l0ZXMiKSkpCgpubWRzXzIwMjFfZGF0LjIgPC0gY2JpbmQobm1kczEuMjAyMS4yLmRmLCBubWRzMi4yMDIxLjIpICU+JQogIHNlbGVjdChudXRfdHJ0OmdyYXppbmdfaGlzdCwgTk1EUzEsIE5NRFMyKQpgYGAKCmBgYHtyfQpnZ3Bsb3Qobm1kc18yMDIxX2RhdC4yLCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IG51dF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMjEgKEhJR0gpIC0gR3JvdXBpbmcgYnkgTnV0cmllbnQgVHJlYXRtZW50IikKCmdncGxvdChubWRzXzIwMjFfZGF0LjIsIGFlcyhOTURTMSwgTk1EUzIsICBmaWxsID0gcHB0X3RydCkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsgCiAgY3VzdG9tX2NvbG9ycyArIAogIGxhYnModGl0bGUgPSAiMjAyMSAoSElHSCkgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpCmBgYAoKIyMjIyBubWRzIDIwMjEKCltTdHJlc3M6XXsudW5kZXJsaW5lfSAqZmFpcioKCmBgYCAgICAgICAgIAowLjEyMzA4MzEKYGBgCgojIyMjIyBtZXRhTURTKCkKCmBgYHtyfQpubWRzLjIwMjEgPC0gbWV0YU1EUyhtYXRyaXguYnJheS4yMDIxLCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLjIwMjEKc3RyZXNzcGxvdChubWRzLjIwMjEpCnBsb3Qobm1kcy4yMDIxLCB0eXBlPSJ0IikKCm5tZHMxLjIwMjEgPC0gYXMuZGF0YS5mcmFtZShzY29yZXMobm1kcy4yMDIxLCBjaG9pY2VzPWMoMSksIGRpc3BsYXk9Yygic2l0ZXMiKSkpICU+JQogIG11dGF0ZSgKICAgIG51dF90cnQgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEpLCAiXyIpLCBgW2AsIDEpLAogICAgcHB0X3RydCA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAyMSksICJfIiksIGBbYCwgMiksCiAgICB5ciA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAyMSksICJfIiksIGBbYCwgMyksCiAgICBncmF6aW5nX2hpc3QgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEpLCAiXyIpLCBgW2AsIDQpCiAgKQpubWRzMi4yMDIxIDwtIGFzLmRhdGEuZnJhbWUoc2NvcmVzKG5tZHMuMjAyMSwgY2hvaWNlcz1jKDIpLCBkaXNwbGF5PWMoInNpdGVzIikpKQoKbm1kc18yMDIxX2RhdCA8LSBjYmluZChubWRzMS4yMDIxLCBubWRzMi4yMDIxKSAlPiUKICBzZWxlY3QobnV0X3RydDpncmF6aW5nX2hpc3QsIE5NRFMxLCBOTURTMikKYGBgCgojIyMjIyBwbG90CgpgYGB7cn0KZ2dwbG90KG5tZHNfMjAyMV9kYXQsIGFlcyhOTURTMSwgTk1EUzIsICBjb2xvciA9IGdyYXppbmdfaGlzdCwgc2hhcGUgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiMjAyMSAtIEdyb3VwaW5nIGJ5IEdyYXppbmcgSGlzdG9yeSAmIE51dHJpZW50IFRyZWF0bWVudCIpCgpnZ3Bsb3Qobm1kc18yMDIxX2RhdCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDIxIC0gR3JvdXBpbmcgYnkgTnV0cmllbnQgVHJlYXRtZW50IikKCmdncGxvdChubWRzXzIwMjFfZGF0LCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IHBwdF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMjEgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpCmBgYAoKIyMjIDIwMjEgLS0tIGJsb2NrcwoKIyMjIyBkYXRhIHdyYW5nbGluZwoKYGBge3J9CiMgcmVsYXRpdml6ZSBkYXRhIHdpdGggQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eQptYXRyaXguMjAyMS5ibG9jayA8LSBtYXRyaXgwLmJsb2NrICU+JQogIGZpbHRlcih5ciA9PSAyMDIxKQoKcm93LjIwMjEuYmxvY2sgPC0gcGFzdGUobWF0cml4LjIwMjEuYmxvY2skbnV0X3RydCwgbWF0cml4LjIwMjEuYmxvY2skcHB0X3RydCwgbWF0cml4LjIwMjEuYmxvY2skeXIsIG1hdHJpeC4yMDIxLmJsb2NrJGJsb2NrLCBzZXAgPSAiXyIpCgptYXRyaXguMjAyMS5ibG9jayA8LSBtYXRyaXguMjAyMS5ibG9ja1ssIGMoNTo3OSldCgpyb3duYW1lcyhtYXRyaXguMjAyMS5ibG9jaykgPC0gcm93LjIwMjEuYmxvY2sKCm1hdHJpeC5icmF5LmJsb2NrLjIwMjEgPC0gZGVjb3N0YW5kKG1hdHJpeC4yMDIxLmJsb2NrLCAidG90YWwiKQpgYGAKCiMjIyMgbm1kcyAyMDIxCgpbU3RyZXNzOl17LnVuZGVybGluZX0gKmZhaXIqCgpgYGAgICAgICAgICAKMC4xNzAyOTQ0CmBgYAoKIyMjIyMgbWV0YU1EUygpCgpgYGB7cn0Kbm1kcy4yMDIxLmJsb2NrIDwtIG1ldGFNRFMobWF0cml4LmJyYXkuYmxvY2suMjAyMSwgaz0yLCB0cnltYXggPSAyNSkKbm1kcy4yMDIxLmJsb2NrCnN0cmVzc3Bsb3Qobm1kcy4yMDIxLmJsb2NrKQpwbG90KG5tZHMuMjAyMS5ibG9jaywgdHlwZT0idCIpCgpubWRzMS4yMDIxLmJsb2NrIDwtIGFzLmRhdGEuZnJhbWUoc2NvcmVzKG5tZHMuMjAyMS5ibG9jaywgY2hvaWNlcz1jKDEpLCBkaXNwbGF5PWMoInNpdGVzIikpKSAlPiUKICBtdXRhdGUoCiAgICBudXRfdHJ0ID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC4yMDIxLmJsb2NrKSwgIl8iKSwgYFtgLCAxKSwKICAgIHBwdF90cnQgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEuYmxvY2spLCAiXyIpLCBgW2AsIDIpLAogICAgeXIgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEuYmxvY2spLCAiXyIpLCBgW2AsIDMpLAogICAgYmxvY2sgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEuYmxvY2spLCAiXyIpLCBgW2AsIDQpCiAgKQpubWRzMi4yMDIxLmJsb2NrIDwtIGFzLmRhdGEuZnJhbWUoc2NvcmVzKG5tZHMuMjAyMS5ibG9jaywgY2hvaWNlcz1jKDIpLCBkaXNwbGF5PWMoInNpdGVzIikpKQoKbm1kc18yMDIxX2RhdC5ibG9jayA8LSBjYmluZChubWRzMS4yMDIxLmJsb2NrLCBubWRzMi4yMDIxLmJsb2NrKSAlPiUKICBzZWxlY3QobnV0X3RydDpibG9jaywgTk1EUzEsIE5NRFMyKQpgYGAKCiMjIyMjIHBsb3QKCmBgYHtyfQpnZ3Bsb3Qobm1kc18yMDIxX2RhdC5ibG9jaywgYWVzKE5NRFMxLCBOTURTMiwgIGNvbG9yID0gYmxvY2ssIHNoYXBlID0gbnV0X3RydCkpICsKICBnZW9tX3BvaW50KHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsKICBsYWJzKHRpdGxlID0gIjIwMjEgKEJsb2NrKSAtIEdyb3VwaW5nIGJ5IEJsb2NrICYgTnV0cmllbnQgVHJlYXRtZW50IikKCmdncGxvdChubWRzXzIwMjFfZGF0LmJsb2NrLCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IG51dF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMjEgKEJsb2NrKSAtIEdyb3VwaW5nIGJ5IE51dHJpZW50IFRyZWF0bWVudCIpCgpnZ3Bsb3Qobm1kc18yMDIxX2RhdC5ibG9jaywgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBwcHRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDIxIChCbG9jaykgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpCmBgYAoKIyMjIDIwMjEgLS0tIGJsb2NrcyAoTE9XKQoKIyMjIyBkYXRhIHdyYW5nbGluZwoKYGBge3J9CiMgcmVsYXRpdml6ZSBkYXRhIHdpdGggQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eQptYXRyaXguMjAyMS5ibG9jay5sb3cgPC0gbWF0cml4MC5ibG9jayAlPiUKICBmaWx0ZXIoeXIgPT0gMjAyMSwKICAgICAgICAgYmxvY2sgPT0gMyB8IGJsb2NrID09IDQpCgpyb3cuMjAyMS5ibG9jay5sb3cgPC0gcGFzdGUobWF0cml4LjIwMjEuYmxvY2subG93JG51dF90cnQsIG1hdHJpeC4yMDIxLmJsb2NrLmxvdyRwcHRfdHJ0LCBtYXRyaXguMjAyMS5ibG9jay5sb3ckeXIsIG1hdHJpeC4yMDIxLmJsb2NrLmxvdyRibG9jaywgc2VwID0gIl8iKQoKbWF0cml4LjIwMjEuYmxvY2subG93IDwtIG1hdHJpeC4yMDIxLmJsb2NrLmxvd1ssIC1jKDA6NCldCgpyb3duYW1lcyhtYXRyaXguMjAyMS5ibG9jay5sb3cpIDwtIHJvdy4yMDIxLmJsb2NrLmxvdwoKbWF0cml4LmJyYXkuYmxvY2suMjAyMS5sb3cgPC0gZGVjb3N0YW5kKG1hdHJpeC4yMDIxLmJsb2NrLmxvdywgInRvdGFsIikKYGBgCgojIyMjIG5tZHMgMjAyMQoKW1N0cmVzczpdey51bmRlcmxpbmV9ICpmYWlyKgoKYGBgICAgICAgICAgCjAuMTI4MjI5NgpgYGAKCiMjIyMjIG1ldGFNRFMoKQoKYGBge3J9Cm5tZHMuMjAyMS5ibG9jay5sb3cgPC0gbWV0YU1EUyhtYXRyaXguYnJheS5ibG9jay4yMDIxLmxvdywgaz0yLCB0cnltYXggPSAyNSkKbm1kcy4yMDIxLmJsb2NrLmxvdwpzdHJlc3NwbG90KG5tZHMuMjAyMS5ibG9jay5sb3cpCnBsb3Qobm1kcy4yMDIxLmJsb2NrLmxvdywgdHlwZT0idCIpCgpubWRzMS4yMDIxLmJsb2NrLmxvdyA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuYmxvY2subG93LCBjaG9pY2VzPWMoMSksIGRpc3BsYXk9Yygic2l0ZXMiKSkpICU+JQogIG11dGF0ZSgKICAgIG51dF90cnQgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEuYmxvY2subG93KSwgIl8iKSwgYFtgLCAxKSwKICAgIHBwdF90cnQgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEuYmxvY2subG93KSwgIl8iKSwgYFtgLCAyKSwKICAgIHlyID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC4yMDIxLmJsb2NrLmxvdyksICJfIiksIGBbYCwgMyksCiAgICBibG9jayA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAyMS5ibG9jay5sb3cpLCAiXyIpLCBgW2AsIDQpCiAgKQpubWRzMi4yMDIxLmJsb2NrLmxvdyA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuYmxvY2subG93LCBjaG9pY2VzPWMoMiksIGRpc3BsYXk9Yygic2l0ZXMiKSkpCgpubWRzXzIwMjFfZGF0LmJsb2NrLmxvdyA8LSBjYmluZChubWRzMS4yMDIxLmJsb2NrLmxvdywgbm1kczIuMjAyMS5ibG9jay5sb3cpICU+JQogIHNlbGVjdChudXRfdHJ0OmJsb2NrLCBOTURTMSwgTk1EUzIpCmBgYAoKIyMjIyMgcGxvdAoKYGBge3J9CmdncGxvdChubWRzXzIwMjFfZGF0LmJsb2NrLmxvdywgYWVzKE5NRFMxLCBOTURTMiwgIGNvbG9yID0gYmxvY2ssIHNoYXBlID0gbnV0X3RydCkpICsKICBnZW9tX3BvaW50KHNpemUgPSA0LCBzdHJva2UgPSAwLjUpICsKICBsYWJzKHRpdGxlID0gIjIwMjEgKEJsb2NrOyBMT1cpIC0gR3JvdXBpbmcgYnkgQmxvY2sgJiBOdXRyaWVudCBUcmVhdG1lbnQiKQoKZ2dwbG90KG5tZHNfMjAyMV9kYXQuYmxvY2subG93LCBhZXMoTk1EUzEsIE5NRFMyLCAgZmlsbCA9IG51dF90cnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBzaXplID0gNCwgc3Ryb2tlID0gMC41KSArIAogIGN1c3RvbV9jb2xvcnMgKyAKICBsYWJzKHRpdGxlID0gIjIwMjEgKEJsb2NrOyBMT1cpIC0gR3JvdXBpbmcgYnkgTnV0cmllbnQgVHJlYXRtZW50IikKCmdncGxvdChubWRzXzIwMjFfZGF0LmJsb2NrLmxvdywgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBwcHRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDIxIChCbG9jazsgTE9XKSAtIEdyb3VwaW5nIGJ5IFByZWNpcGl0YXRpb24gVHJlYXRtZW50IikKYGBgCgojIyMgMjAyMSAtLS0gYmxvY2tzIChISUdIKQoKIyMjIyBkYXRhIHdyYW5nbGluZwoKYGBge3J9CiMgcmVsYXRpdml6ZSBkYXRhIHdpdGggQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eQptYXRyaXguMjAyMS5ibG9jay5oaWdoIDwtIG1hdHJpeDAuYmxvY2sgJT4lCiAgZmlsdGVyKHlyID09IDIwMjEsCiAgICAgICAgIGJsb2NrID09IDEgfCBibG9jayA9PSAyKQoKcm93LjIwMjEuYmxvY2suaGlnaCA8LSBwYXN0ZShtYXRyaXguMjAyMS5ibG9jay5oaWdoJG51dF90cnQsIG1hdHJpeC4yMDIxLmJsb2NrLmhpZ2gkcHB0X3RydCwgbWF0cml4LjIwMjEuYmxvY2suaGlnaCR5ciwgbWF0cml4LjIwMjEuYmxvY2suaGlnaCRibG9jaywgc2VwID0gIl8iKQoKbWF0cml4LjIwMjEuYmxvY2suaGlnaCA8LSBtYXRyaXguMjAyMS5ibG9jay5oaWdoWywgLWMoMDo0KV0KCnJvd25hbWVzKG1hdHJpeC4yMDIxLmJsb2NrLmhpZ2gpIDwtIHJvdy4yMDIxLmJsb2NrLmhpZ2gKCm1hdHJpeC5icmF5LmJsb2NrLjIwMjEuaGlnaCA8LSBkZWNvc3RhbmQobWF0cml4LjIwMjEuYmxvY2suaGlnaCwgInRvdGFsIikKYGBgCgojIyMjIG5tZHMgMjAyMQoKW1N0cmVzczpdey51bmRlcmxpbmV9ICpmYWlyKgoKYGBgICAgICAgICAgCjAuMTQxMjk5NwpgYGAKCiMjIyMjIG1ldGFNRFMoKQoKYGBge3J9Cm5tZHMuMjAyMS5ibG9jay5oaWdoIDwtIG1ldGFNRFMobWF0cml4LmJyYXkuYmxvY2suMjAyMS5oaWdoLCBrPTIsIHRyeW1heCA9IDI1KQpubWRzLjIwMjEuYmxvY2suaGlnaApzdHJlc3NwbG90KG5tZHMuMjAyMS5ibG9jay5oaWdoKQpwbG90KG5tZHMuMjAyMS5ibG9jay5oaWdoLCB0eXBlPSJ0IikKCm5tZHMxLjIwMjEuYmxvY2suaGlnaCA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuYmxvY2suaGlnaCwgY2hvaWNlcz1jKDEpLCBkaXNwbGF5PWMoInNpdGVzIikpKSAlPiUKICBtdXRhdGUoCiAgICBudXRfdHJ0ID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC4yMDIxLmJsb2NrLmhpZ2gpLCAiXyIpLCBgW2AsIDEpLAogICAgcHB0X3RydCA9IHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhtYXRyaXguMjAyMS5ibG9jay5oaWdoKSwgIl8iKSwgYFtgLCAyKSwKICAgIHlyID0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKG1hdHJpeC4yMDIxLmJsb2NrLmhpZ2gpLCAiXyIpLCBgW2AsIDMpLAogICAgYmxvY2sgPSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMobWF0cml4LjIwMjEuYmxvY2suaGlnaCksICJfIiksIGBbYCwgNCkKICApCm5tZHMyLjIwMjEuYmxvY2suaGlnaCA8LSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhubWRzLjIwMjEuYmxvY2suaGlnaCwgY2hvaWNlcz1jKDIpLCBkaXNwbGF5PWMoInNpdGVzIikpKQoKbm1kc18yMDIxX2RhdC5ibG9jay5oaWdoIDwtIGNiaW5kKG5tZHMxLjIwMjEuYmxvY2suaGlnaCwgbm1kczIuMjAyMS5ibG9jay5oaWdoKSAlPiUKICBzZWxlY3QobnV0X3RydDpibG9jaywgTk1EUzEsIE5NRFMyKQpgYGAKCiMjIyMjIHBsb3QKCmBgYHtyfQpnZ3Bsb3Qobm1kc18yMDIxX2RhdC5ibG9jay5oaWdoLCBhZXMoTk1EUzEsIE5NRFMyLCAgY29sb3IgPSBibG9jaywgc2hhcGUgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiMjAyMSAoQmxvY2s7IEhJR0gpIC0gR3JvdXBpbmcgYnkgQmxvY2sgJiBOdXRyaWVudCBUcmVhdG1lbnQiKQoKZ2dwbG90KG5tZHNfMjAyMV9kYXQuYmxvY2suaGlnaCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBudXRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDIxIChCbG9jazsgSElHSCkgLSBHcm91cGluZyBieSBOdXRyaWVudCBUcmVhdG1lbnQiKQoKZ2dwbG90KG5tZHNfMjAyMV9kYXQuYmxvY2suaGlnaCwgYWVzKE5NRFMxLCBOTURTMiwgIGZpbGwgPSBwcHRfdHJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDQsIHN0cm9rZSA9IDAuNSkgKyAKICBjdXN0b21fY29sb3JzICsgCiAgbGFicyh0aXRsZSA9ICIyMDIxIChCbG9jazsgSElHSCkgLSBHcm91cGluZyBieSBQcmVjaXBpdGF0aW9uIFRyZWF0bWVudCIpCmBgYAoKIyMgTWFrZSBzcGVjaWVzIHggdHJhaXQgbWF0cml4CgpHcmVlbmhvdXNlIHRyYWl0cwoKLSAgIGhlaWdodCwgbGVhZiBkcnkgbWF0dGVyIGNvbnRlbnQsIHNwZWNpZmljIGxlYWYgYXJlYSwgcm9vdCBtYXNzIGZyYWN0aW9uLCByZWxhdGl2ZSBncm93dGggcmF0ZSwgY29hcnNlIHJvb3QgZGlhbWV0ZXIsIHJvb3QgZGVuc2l0eSwgc3BlY2lmaWMgcm9vdCBsZW5ndGggb2YgZmluZSByb290cywgc3BlY2lmaWMgcm9vdCBsZW5ndGggb2YgY29hcnNlIHJvb3RzCgpGaWVsZCB0cmFpdHMKCi0gICBoZWlnaHQsIGxlYWYgZHJ5IG1hdHRlciBjb250ZW50LCBzcGVjaWZpYyBsZWFmIGFyZWEsIHNlZWQgbWFzcywgbGVhZiBDLCBsZWFmIE4KClsiSDE6XXsudW5kZXJsaW5lfSBQYWlyaW5nIGZpZWxkIHJlc3VsdHMgd2l0aCBhIGdyZWVuaG91c2UgMTUgTiBleHBlcmltZW50IHdpbGwgYWxsb3cgdXMgdG8gcmVsYXRlIHNwZWNpZXMgcmVzcG9uc2VzIHRvIHRoZWlyIGFiaWxpdHkgdG8gdXB0YWtlIG9yZ2FuaWMgTiIKCiJJbiBhZGRpdGlvbiwgd2Ugd2lsbCBjb25kdWN0IGEgZ3JlZW5ob3VzZSBleHBlcmltZW50IHRvIGlzb2xhdGUgdGhlIG1lY2hhbmlzbSAobWluZXJhbGl6ZWQgTiB2cyBvcmdhbmljIE4gdXB0YWtlIHJhdGVzICkgYnkgd2hpY2ggY29tcG9zdCBtYXkgYWZmZWN0IHNwZWNpZXMgY29tcG9zaXRpb24iCgpXb3JrZmxvdyBwbGFuOgoKLSAgIG92ZXJsYXkgc3BlY2llcyB0cmFpdCBkYXRhIGFzIHZlY3RvcnMgb24gdGhlIE5NRFMKCiAgICAtICAgb25seSBncmVlbmhvdXNlIHRyYWl0cyBhdmFpbGFibGUgKG9ubHkgc2xhIGRhdGEgZnJvbSBmaWVsZCkKCiAgICAgICAgLSAgIHVzZSBQQyBzY29yZXMgYXMgY29tcG9zaXRlIHRyYWl0IGF4ZXMgT1IKCiAgICAgICAgLSAgIGF2ZXJhZ2UgdGhlIHRyYWl0cyBmb3IgZWFjaCBzcGVjaWVzCgojIyMgUmVhZCBpbiB0cmFpdCBkYXRhCgpgYGB7cn0KIyByZWFkIGluIGdyZWVuaG91c2UgdHJhaXQgZGF0YQp0cmFpdHMuZ2ggPC0gcmVhZC5jc3YoImh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3NjbC9maS9jOHZrMzFhODA3eGc0OGplejFqMDMvR3JlZW5ob3VzZVRyYWl0cy5jc3Y/cmxrZXk9Y2E3MzZlYTI3azc5bW83aDhkYm42N3FpcSZzdD15YTFjazZwNyZkbD0xIikKCiMgcmVhZCBpbiBmaWVsZCB0cmFpdCBkYXRhCiMgZG93bmxvYWQuZmlsZSgiaHR0cHM6Ly93d3cuZHJvcGJveC5jb20vc2NsL2ZpL3RycXJuejU0ZGtqb2E5ZG80dGxlNS9sZWFmLWFyZWEtZGF0YV9ORy54bHN4P3Jsa2V5PXMwa2ljMmE1eXFrbmlrYzRpY2VrOHk3cm4mc3Q9ZGw0eDYzNGgmZGw9MSIsZGVzdGZpbGUgPSAiZmllbGRfc2xhLnhsc3giKQp0cmFpdHMuc2xhLmZpZWxkIDwtIAogIHJlYWRfZXhjZWwoImZpZWxkX3NsYS54bHN4Iixjb2xfbmFtZXMgPSBUUlVFLGNvbF90eXBlcyA9ICJ0ZXh0IikKCnJkYSh0cmFpdHMuZ2gsIHNjYWxlID0gVFJVRSkKYGBgCgojIyMgU3VtbWFyaXplIHRyYWl0IGRhdGEgKEdIKSBmb3IgZWFjaCBzcGVjaWVzCgojIyMjIG1lYW5zCgpgYGB7cn0KdHJhaXRzLmdoLm1lYW5zIDwtIHRyYWl0cy5naCAlPiUKICBtdXRhdGUoYWNyb3NzKDQ6KG5jb2wodHJhaXRzLmdoKSAtIDEpLCBhcy5udW1lcmljKSkgJT4lCiAgZ3JvdXBfYnkoSUQpICU+JQogIHN1bW1hcmlzZSgKICAgIGFjcm9zcyg0OihuY29sKHRyYWl0cy5naCkgLSAxKSwgbGlzdChtZWFuID0gfm1lYW4oLngsIG5hLnJtID0gVFJVRSkjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNkID0gfnNkKC54LCBuYS5ybSA9IFRSVUUpKSkKICAgICkpCiAgKQoKIyBzZXRkaWZmKGNvbG5hbWVzKG1hdHJpeC5icmF5KSwgdHJhaXRzLmdoLm1lYW5zJElEKQojIHNldGRpZmYodHJhaXRzLmdoLm1lYW5zJElELCBjb2xuYW1lcyhtYXRyaXguYnJheSkpCnRyYWl0cy5naC5tZWFuczIgPC0gdHJhaXRzLmdoLm1lYW5zICU+JQogIGZpbHRlcihJRCAlaW4lIGludGVyc2VjdChjb2xuYW1lcyhtYXRyaXguYnJheSksIHRyYWl0cy5naC5tZWFucyRJRCkpCnJvd25hbWVzKHRyYWl0cy5naC5tZWFuczIpIDwtIGFzLmNoYXJhY3Rlcih0cmFpdHMuZ2gubWVhbnMyJElEKQoKbWF0cml4LmJyYXkgJT4lCiAgc2VsZWN0KGFsbF9vZihpbnRlcnNlY3QoY29sbmFtZXMobWF0cml4LmJyYXkpLCB0cmFpdHMuZ2gubWVhbnMkSUQpKSkgIyBpcyB0aGlzIGFwcHJvcHJpYXRlPyBzaG91bGQgaSByZWxhdGl2aXplIGl0IGFsbCBvbmx5IHdpdGggdGhlc2Ugc3BlY2llcyBpbnN0ZWFkIG9mIGp1c3QgY3V0dGluZyBvdXQgc3BlY2llcz8Kbm1kcy5jb21wLjIgPC0gbWV0YU1EUyhtYXRyaXguYnJheSAlPiUKICBzZWxlY3QoYWxsX29mKGludGVyc2VjdChjb2xuYW1lcyhtYXRyaXguYnJheSksIHRyYWl0cy5naC5tZWFucyRJRCkpKSwgaz0yLCB0cnltYXggPSAyNSkKbm1kcy5jb21wLjIgIyBwcmV0dHkgbm90IGdyZWF0IHN0cmVzcwpzdHJlc3NwbG90KG5tZHMuY29tcC4yKQpwbG90KG5tZHMuY29tcC4yLCB0eXBlPSJ0IikKCmVudmZpdChubWRzLmNvbXAuMiwgdHJhaXRzLmdoLm1lYW5zMiwgcGVybXV0YXRpb25zID0gOTk5KQpgYGAKCikK